* Move the iterator to the next record in the snapshot. Adjust the fields in * `iter` and return `ITER_OK` or `ITER_DONE`. This function does not free the * iterator in the case of `ITER_DONE`. */
| 884 | * iterator in the case of `ITER_DONE`. |
| 885 | */ |
| 886 | static int next_record(struct packed_ref_iterator *iter) |
| 887 | { |
| 888 | const char *p, *eol; |
| 889 | |
| 890 | memset(&iter->base.ref, 0, sizeof(iter->base.ref)); |
| 891 | strbuf_reset(&iter->refname_buf); |
| 892 | |
| 893 | /* |
| 894 | * If iter->pos is contained within a skipped region, jump past |
| 895 | * it. |
| 896 | * |
| 897 | * Note that each skipped region is considered at most once, |
| 898 | * since they are ordered based on their starting position. |
| 899 | */ |
| 900 | while (iter->jump_cur < iter->jump_nr) { |
| 901 | struct jump_list_entry *curr = &iter->jump[iter->jump_cur]; |
| 902 | if (iter->pos < curr->start) |
| 903 | break; /* not to the next jump yet */ |
| 904 | |
| 905 | iter->jump_cur++; |
| 906 | if (iter->pos < curr->end) { |
| 907 | iter->pos = curr->end; |
| 908 | trace2_counter_add(TRACE2_COUNTER_ID_PACKED_REFS_JUMPS, 1); |
| 909 | /* jumps are coalesced, so only one jump is necessary */ |
| 910 | break; |
| 911 | } |
| 912 | } |
| 913 | |
| 914 | if (iter->pos == iter->eof) |
| 915 | return ITER_DONE; |
| 916 | |
| 917 | iter->base.ref.flags = REF_ISPACKED; |
| 918 | p = iter->pos; |
| 919 | |
| 920 | if (iter->eof - p < snapshot_hexsz(iter->snapshot) + 2 || |
| 921 | parse_oid_hex_algop(p, &iter->oid, &p, iter->repo->hash_algo) || |
| 922 | !isspace(*p++)) |
| 923 | die_invalid_line(iter->snapshot->refs->path, |
| 924 | iter->pos, iter->eof - iter->pos); |
| 925 | iter->base.ref.oid = &iter->oid; |
| 926 | |
| 927 | eol = memchr(p, '\n', iter->eof - p); |
| 928 | if (!eol) |
| 929 | die_unterminated_line(iter->snapshot->refs->path, |
| 930 | iter->pos, iter->eof - iter->pos); |
| 931 | |
| 932 | strbuf_add(&iter->refname_buf, p, eol - p); |
| 933 | iter->base.ref.name = iter->refname_buf.buf; |
| 934 | |
| 935 | if (refname_contains_nul(&iter->refname_buf)) |
| 936 | die("packed refname contains embedded NULL: %s", iter->base.ref.name); |
| 937 | |
| 938 | if (check_refname_format(iter->base.ref.name, REFNAME_ALLOW_ONELEVEL)) { |
| 939 | if (!refname_is_safe(iter->base.ref.name)) |
| 940 | die("packed refname is dangerous: %s", |
| 941 | iter->base.ref.name); |
| 942 | oidclr(&iter->oid, iter->repo->hash_algo); |
| 943 | iter->base.ref.flags |= REF_BAD_NAME | REF_ISBROKEN; |
no test coverage detected