Skip to content

Commit c26d8a8

Browse files
committed
sha256: further API simplifications for OID parsing
Introduce `git_oid_from_string`, `git_oid_from_prefix`, and `git_oid_from_raw`, all of which take a `git_oid_t` that indicates what type of OID should be parsed (SHA1 or SHA256). This allows users to continue to use `git_oid_fromstr` without any code changes, while remaining in a SHA1 world. Note that these are not perfect analogs to the `fromstr` APIs. * `git_oid_from_string` now takes a NUL terminated string, instead of allowing for non-NUL terminated strings. Adding a NUL check feels like an important safety consideration for C strings. * `git_oid_from_prefix` should be used for an OID substring and length. Previous usages of `git_oid_fromstr` with non-NUL terminated strings should move to `git_oid_from_prefix` with the hexsize for the given OID type.
1 parent 56e2a85 commit c26d8a8

File tree

184 files changed

+1041
-1021
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

184 files changed

+1041
-1021
lines changed

examples/general.c

+8-8
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ static void oid_parsing(git_oid *oid)
143143
* key we're working with.
144144
*/
145145
#ifdef GIT_EXPERIMENTAL_SHA256
146-
git_oid_fromstr(oid, hex, GIT_OID_SHA1);
146+
git_oid_from_string(oid, hex, GIT_OID_SHA1);
147147
#else
148148
git_oid_fromstr(oid, hex);
149149
#endif
@@ -292,8 +292,8 @@ static void commit_writing(git_repository *repo)
292292
* but you can also use
293293
*/
294294
#ifdef GIT_EXPERIMENTAL_SHA256
295-
git_oid_fromstr(&tree_id, "f60079018b664e4e79329a7ef9559c8d9e0378d1", GIT_OID_SHA1);
296-
git_oid_fromstr(&parent_id, "5b5b025afb0b4c913b4c338a42934a3863bf3644", GIT_OID_SHA1);
295+
git_oid_from_string(&tree_id, "f60079018b664e4e79329a7ef9559c8d9e0378d1", GIT_OID_SHA1);
296+
git_oid_from_string(&parent_id, "5b5b025afb0b4c913b4c338a42934a3863bf3644", GIT_OID_SHA1);
297297
#else
298298
git_oid_fromstr(&tree_id, "f60079018b664e4e79329a7ef9559c8d9e0378d1");
299299
git_oid_fromstr(&parent_id, "5b5b025afb0b4c913b4c338a42934a3863bf3644");
@@ -363,7 +363,7 @@ static void commit_parsing(git_repository *repo)
363363
printf("\n*Commit Parsing*\n");
364364

365365
#ifdef GIT_EXPERIMENTAL_SHA256
366-
git_oid_fromstr(&oid, "8496071c1b46c854b31185ea97743be6a8774479", GIT_OID_SHA1);
366+
git_oid_from_string(&oid, "8496071c1b46c854b31185ea97743be6a8774479", GIT_OID_SHA1);
367367
#else
368368
git_oid_fromstr(&oid, "8496071c1b46c854b31185ea97743be6a8774479");
369369
#endif
@@ -436,7 +436,7 @@ static void tag_parsing(git_repository *repo)
436436
* the same way that we would a commit (or any other object).
437437
*/
438438
#ifdef GIT_EXPERIMENTAL_SHA256
439-
git_oid_fromstr(&oid, "b25fa35b38051e4ae45d4222e795f9df2e43f1d1", GIT_OID_SHA1);
439+
git_oid_from_string(&oid, "b25fa35b38051e4ae45d4222e795f9df2e43f1d1", GIT_OID_SHA1);
440440
#else
441441
git_oid_fromstr(&oid, "b25fa35b38051e4ae45d4222e795f9df2e43f1d1");
442442
#endif
@@ -488,7 +488,7 @@ static void tree_parsing(git_repository *repo)
488488
* Create the oid and lookup the tree object just like the other objects.
489489
*/
490490
#ifdef GIT_EXPERIMENTAL_SHA256
491-
git_oid_fromstr(&oid, "f60079018b664e4e79329a7ef9559c8d9e0378d1", GIT_OID_SHA1);
491+
git_oid_from_string(&oid, "f60079018b664e4e79329a7ef9559c8d9e0378d1", GIT_OID_SHA1);
492492
#else
493493
git_oid_fromstr(&oid, "f60079018b664e4e79329a7ef9559c8d9e0378d1");
494494
#endif
@@ -546,7 +546,7 @@ static void blob_parsing(git_repository *repo)
546546
printf("\n*Blob Parsing*\n");
547547

548548
#ifdef GIT_EXPERIMENTAL_SHA256
549-
git_oid_fromstr(&oid, "1385f264afb75a56a5bec74243be9b367ba4ca08", GIT_OID_SHA1);
549+
git_oid_from_string(&oid, "1385f264afb75a56a5bec74243be9b367ba4ca08", GIT_OID_SHA1);
550550
#else
551551
git_oid_fromstr(&oid, "1385f264afb75a56a5bec74243be9b367ba4ca08");
552552
#endif
@@ -592,7 +592,7 @@ static void revwalking(git_repository *repo)
592592
printf("\n*Revwalking*\n");
593593

594594
#ifdef GIT_EXPERIMENTAL_SHA256
595-
git_oid_fromstr(&oid, "5b5b025afb0b4c913b4c338a42934a3863bf3644", GIT_OID_SHA1);
595+
git_oid_from_string(&oid, "5b5b025afb0b4c913b4c338a42934a3863bf3644", GIT_OID_SHA1);
596596
#else
597597
git_oid_fromstr(&oid, "5b5b025afb0b4c913b4c338a42934a3863bf3644");
598598
#endif

examples/rev-list.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ static int revwalk_parse_revs(git_repository *repo, git_revwalk *walk, struct ar
141141
continue;
142142

143143
#ifdef GIT_EXPERIMENTAL_SHA256
144-
if ((error = git_oid_fromstr(&oid, curr, GIT_OID_SHA1)))
144+
if ((error = git_oid_from_string(&oid, curr, GIT_OID_SHA1)))
145145
return error;
146146
#else
147147
if ((error = git_oid_fromstr(&oid, curr)))

include/git2/oid.h

+55-7
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,62 @@ typedef struct git_oid {
114114

115115
#ifdef GIT_EXPERIMENTAL_SHA256
116116

117-
GIT_EXTERN(int) git_oid_fromstr(git_oid *out, const char *str, git_oid_t type);
118-
GIT_EXTERN(int) git_oid_fromstrp(git_oid *out, const char *str, git_oid_t type);
119-
GIT_EXTERN(int) git_oid_fromstrn(git_oid *out, const char *str, size_t length, git_oid_t type);
120-
GIT_EXTERN(int) git_oid_fromraw(git_oid *out, const unsigned char *raw, git_oid_t type);
117+
/**
118+
* Parse a NUL terminated hex formatted object id string into a `git_oid`.
119+
*
120+
* The given string must be NUL terminated, and must be the hex size of
121+
* the given object ID type - 40 characters for SHA1, 64 characters for
122+
* SHA256.
123+
*
124+
* To parse an incomplete object ID (an object ID prefix), or a sequence
125+
* of characters that is not NUL terminated, use `git_oid_from_prefix`.
126+
*
127+
* @param out oid structure the result is written into.
128+
* @param str input hex string
129+
* @param type object id type
130+
* @return 0 or an error code
131+
*/
132+
GIT_EXTERN(int) git_oid_from_string(
133+
git_oid *out,
134+
const char *str,
135+
git_oid_t type);
121136

122-
#else
137+
/**
138+
* Parse the given number of characters out of a hex formatted object id
139+
* string into a `git_oid`.
140+
*
141+
* The given length can be between 0 and the hex size for the given object ID
142+
* type - 40 characters for SHA1, 64 characters for SHA256. The remainder of
143+
* the `git_oid` will be set to zeros.
144+
*
145+
* @param out oid structure the result is written into.
146+
* @param str input hex prefix
147+
* @param type object id type
148+
* @return 0 or an error code
149+
*/
150+
GIT_EXTERN(int) git_oid_from_prefix(
151+
git_oid *out,
152+
const char *str,
153+
size_t len,
154+
git_oid_t type);
155+
156+
/**
157+
* Parse a raw object id into a `git_oid`.
158+
*
159+
* The appropriate number of bytes for the given object ID type will
160+
* be read from the byte array - 20 bytes for SHA1, 32 bytes for SHA256.
161+
*
162+
* @param out oid structure the result is written into.
163+
* @param raw raw object ID bytes
164+
* @param type object id type
165+
* @return 0 or an error code
166+
*/
167+
GIT_EXTERN(int) git_oid_from_raw(
168+
git_oid *out,
169+
const unsigned char *raw,
170+
git_oid_t type);
171+
172+
#endif
123173

124174
/**
125175
* Parse a hex formatted object id into a git_oid.
@@ -168,8 +218,6 @@ GIT_EXTERN(int) git_oid_fromstrn(git_oid *out, const char *str, size_t length);
168218
*/
169219
GIT_EXTERN(int) git_oid_fromraw(git_oid *out, const unsigned char *raw);
170220

171-
#endif
172-
173221
/**
174222
* Format a git_oid into a hex string.
175223
*

src/libgit2/commit_graph.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ static int git_commit_graph_entry_get_byindex(
502502
}
503503

504504
commit_data = file->commit_data + pos * (oid_size + 4 * sizeof(uint32_t));
505-
git_oid__fromraw(&e->tree_oid, commit_data, file->oid_type);
505+
git_oid_from_raw(&e->tree_oid, commit_data, file->oid_type);
506506
e->parent_indices[0] = ntohl(*((uint32_t *)(commit_data + oid_size)));
507507
e->parent_indices[1] = ntohl(
508508
*((uint32_t *)(commit_data + oid_size + sizeof(uint32_t))));
@@ -536,7 +536,7 @@ static int git_commit_graph_entry_get_byindex(
536536
}
537537
}
538538

539-
git_oid__fromraw(&e->sha1, &file->oid_lookup[pos * oid_size], file->oid_type);
539+
git_oid_from_raw(&e->sha1, &file->oid_lookup[pos * oid_size], file->oid_type);
540540
return 0;
541541
}
542542

src/libgit2/fetch.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ static int maybe_want_oid(git_remote *remote, git_refspec *spec)
8080
oid_head = git__calloc(1, sizeof(git_remote_head));
8181
GIT_ERROR_CHECK_ALLOC(oid_head);
8282

83-
git_oid__fromstr(&oid_head->oid, spec->src, remote->repo->oid_type);
83+
git_oid_from_string(&oid_head->oid, spec->src, remote->repo->oid_type);
8484

8585
if (spec->dst) {
8686
oid_head->name = git__strdup(spec->dst);

src/libgit2/fetchhead.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ static int fetchhead_ref_parse(
202202
return -1;
203203
}
204204

205-
if (git_oid__fromstr(oid, oid_str, oid_type) < 0) {
205+
if (git_oid_from_string(oid, oid_str, oid_type) < 0) {
206206
const git_error *oid_err = git_error_last();
207207
const char *err_msg = oid_err ? oid_err->message : "invalid object ID";
208208

src/libgit2/index.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -2364,7 +2364,7 @@ static int read_reuc(git_index *index, const char *buffer, size_t size)
23642364
return index_error_invalid("reading reuc entry oid");
23652365
}
23662366

2367-
if (git_oid__fromraw(&lost->oid[i], (const unsigned char *) buffer, index->oid_type) < 0)
2367+
if (git_oid_from_raw(&lost->oid[i], (const unsigned char *) buffer, index->oid_type) < 0)
23682368
return -1;
23692369

23702370
size -= oid_size;
@@ -2553,14 +2553,14 @@ static int read_entry(
25532553

25542554
switch (index->oid_type) {
25552555
case GIT_OID_SHA1:
2556-
if (git_oid__fromraw(&entry.id, source_sha1.oid,
2556+
if (git_oid_from_raw(&entry.id, source_sha1.oid,
25572557
GIT_OID_SHA1) < 0)
25582558
return -1;
25592559
entry.flags = ntohs(source_sha1.flags);
25602560
break;
25612561
#ifdef GIT_EXPERIMENTAL_SHA256
25622562
case GIT_OID_SHA256:
2563-
if (git_oid__fromraw(&entry.id, source_sha256.oid,
2563+
if (git_oid_from_raw(&entry.id, source_sha256.oid,
25642564
GIT_OID_SHA256) < 0)
25652565
return -1;
25662566
entry.flags = ntohs(source_sha256.flags);

src/libgit2/indexer.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1112,7 +1112,7 @@ static int fix_thin_pack(git_indexer *idx, git_indexer_progress *stats)
11121112
return -1;
11131113
}
11141114

1115-
git_oid__fromraw(&base, base_info, idx->oid_type);
1115+
git_oid_from_raw(&base, base_info, idx->oid_type);
11161116
git_mwindow_close(&w);
11171117

11181118
if (has_entry(idx, &base))

src/libgit2/merge.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ int git_repository_mergehead_foreach(
616616
goto cleanup;
617617
}
618618

619-
if ((error = git_oid__fromstr(&oid, line, repo->oid_type)) < 0)
619+
if ((error = git_oid_from_string(&oid, line, repo->oid_type)) < 0)
620620
goto cleanup;
621621

622622
if ((error = cb(&oid, payload)) != 0) {

src/libgit2/midx.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ int git_midx_entry_find(
449449
return midx_error("invalid index into the packfile names table");
450450
e->pack_index = pack_index;
451451
e->offset = offset;
452-
git_oid__fromraw(&e->sha1, current, idx->oid_type);
452+
git_oid_from_raw(&e->sha1, current, idx->oid_type);
453453
return 0;
454454
}
455455

@@ -467,7 +467,7 @@ int git_midx_foreach_entry(
467467
oid_size = git_oid_size(idx->oid_type);
468468

469469
for (i = 0; i < idx->num_objects; ++i) {
470-
if ((error = git_oid__fromraw(&oid, &idx->oid_lookup[i * oid_size], idx->oid_type)) < 0)
470+
if ((error = git_oid_from_raw(&oid, &idx->oid_lookup[i * oid_size], idx->oid_type)) < 0)
471471
return error;
472472

473473
if ((error = cb(&oid, data)) != 0)

src/libgit2/notes.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,7 @@ static int process_entry_path(
704704
goto cleanup;
705705
}
706706

707-
error = git_oid__fromstr(annotated_object_id, buf.ptr, it->repo->oid_type);
707+
error = git_oid_from_string(annotated_object_id, buf.ptr, it->repo->oid_type);
708708

709709
cleanup:
710710
git_str_dispose(&buf);

src/libgit2/object.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ int git_object__parse_oid_header(
662662
if (buffer[header_len + sha_len] != '\n')
663663
return -1;
664664

665-
if (git_oid__fromstr(oid, buffer + header_len, oid_type) < 0)
665+
if (git_oid_from_prefix(oid, buffer + header_len, sha_len, oid_type) < 0)
666666
return -1;
667667

668668
*buffer_out = buffer + (header_len + sha_len + 1);

src/libgit2/odb_loose.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,10 @@ static int locate_object_short_oid(
552552
return git_odb__error_ambiguous("multiple matches in loose objects");
553553

554554
/* Convert obtained hex formatted oid to raw */
555-
error = git_oid__fromstr(res_oid, (char *)state.res_oid, backend->options.oid_type);
555+
error = git_oid_from_prefix(res_oid, (char *)state.res_oid,
556+
git_oid_hexsize(backend->options.oid_type),
557+
backend->options.oid_type);
558+
556559
if (error)
557560
return error;
558561

0 commit comments

Comments
 (0)