| 822 | } |
| 823 | |
| 824 | static int reftable_log_record_decode(void *rec, struct reftable_buf key, |
| 825 | uint8_t val_type, struct string_view in, |
| 826 | uint32_t hash_size, struct reftable_buf *scratch) |
| 827 | { |
| 828 | struct string_view start = in; |
| 829 | struct reftable_log_record *r = rec; |
| 830 | uint64_t max = 0; |
| 831 | uint64_t ts = 0; |
| 832 | int err, n; |
| 833 | |
| 834 | if (key.len <= 9 || key.buf[key.len - 9] != 0) |
| 835 | return REFTABLE_FORMAT_ERROR; |
| 836 | |
| 837 | REFTABLE_ALLOC_GROW_OR_NULL(r->refname, key.len - 8, r->refname_cap); |
| 838 | if (!r->refname) { |
| 839 | err = REFTABLE_OUT_OF_MEMORY_ERROR; |
| 840 | goto done; |
| 841 | } |
| 842 | |
| 843 | memcpy(r->refname, key.buf, key.len - 8); |
| 844 | ts = reftable_get_be64((unsigned char *)key.buf + key.len - 8); |
| 845 | |
| 846 | r->update_index = (~max) - ts; |
| 847 | |
| 848 | if (val_type != r->value_type) { |
| 849 | switch (r->value_type) { |
| 850 | case REFTABLE_LOG_UPDATE: |
| 851 | REFTABLE_FREE_AND_NULL(r->value.update.message); |
| 852 | r->value.update.message_cap = 0; |
| 853 | REFTABLE_FREE_AND_NULL(r->value.update.email); |
| 854 | REFTABLE_FREE_AND_NULL(r->value.update.name); |
| 855 | break; |
| 856 | case REFTABLE_LOG_DELETION: |
| 857 | break; |
| 858 | } |
| 859 | } |
| 860 | |
| 861 | r->value_type = val_type; |
| 862 | if (val_type == REFTABLE_LOG_DELETION) |
| 863 | return 0; |
| 864 | |
| 865 | if (in.len < 2 * hash_size) { |
| 866 | err = REFTABLE_FORMAT_ERROR; |
| 867 | goto done; |
| 868 | } |
| 869 | |
| 870 | memcpy(r->value.update.old_hash, in.buf, hash_size); |
| 871 | memcpy(r->value.update.new_hash, in.buf + hash_size, hash_size); |
| 872 | |
| 873 | string_view_consume(&in, 2 * hash_size); |
| 874 | |
| 875 | n = decode_string(scratch, in); |
| 876 | if (n < 0) { |
| 877 | err = REFTABLE_FORMAT_ERROR; |
| 878 | goto done; |
| 879 | } |
| 880 | string_view_consume(&in, n); |
| 881 |
nothing calls this directly
no test coverage detected