git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 02/12] load_subtree(): remove unnecessary conditional

From
Junio C Hamano <gitster@pobox.com>
Date
Aug 26, 2017, 16:38 UTC
Message-ID
<xmqqh8wuqo6e.fsf@gitster.mtv.corp.google.com>
In-Reply-To
<c21bedbee9487792f4a336a417aa9874578aaac2.1503734566.git.mhagger@alum.mit.edu>
Michael Haggerty <mhagger@alum.mit.edu> writes:
> At this point in the code, len is *always* <= 20.

This is the kind of log message that makes me unconfortable, as it lacks "because", and the readers would need to find out themselves by following the same codepath the patch author already followed.

There is an assert earlier before the control gets in this loop
	prefix_len = subtree->key_oid.hash[KEY_INDEX];
	assert(prefix_len * 2 >= n);
	memcpy(object_oid.hash, subtree->key_oid.hash, prefix_len);

that tries to ensure there is sufficient number of prefix defined in that key, and the codeflow may ensure that prefix_len is both an even number and shorter than 20 (the correctness of the code depends on these, it seems, and if for some reason prefix_len is much larger, calls to get_oid_hex_segment() will overflow the oid.hash[] array without checking). I'd at least feel safer to have an assert next to the existing one that catches a bug to throw a randomly large value into subtree->key_oid.hash[KEY_INDEX]. Then we can safely say "at this point in the code, len is always <= 20", as that assert will makes it obvious without looking at anything other than this code and get_oid_hex_segment() implementaiton (combined with the fact that this function is the only one that coerces len and puts it into ->key_oid.hash[KEY_INDEX], but that is a weak assurance as we cannot tell where "subtree" came from---it may have full 20-byte oid in its key_oid field---without following the callchain a lot more widely).

Show 52 quoted lines
> Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
> ---
>  notes.c | 35 +++++++++++++++++------------------
>  1 file changed, 17 insertions(+), 18 deletions(-)
>
> diff --git a/notes.c b/notes.c
> index 00630a9396..f7ce64ff48 100644
> --- a/notes.c
> +++ b/notes.c
> @@ -446,25 +446,24 @@ static void load_subtree(struct notes_tree *t, struct leaf_node *subtree,
>  		 * If object SHA1 is incomplete (len < 20), and current
>  		 * component consists of 2 hex chars, assume note subtree
>  		 */
> -		if (len <= GIT_SHA1_RAWSZ) {
> -			type = PTR_TYPE_NOTE;
> -			l = (struct leaf_node *)
> -				xcalloc(1, sizeof(struct leaf_node));
> -			oidcpy(&l->key_oid, &object_oid);
> -			oidcpy(&l->val_oid, entry.oid);
> -			if (len < GIT_SHA1_RAWSZ) {
> -				if (!S_ISDIR(entry.mode) || path_len != 2)
> -					goto handle_non_note; /* not subtree */
> -				l->key_oid.hash[KEY_INDEX] = (unsigned char) len;
> -				type = PTR_TYPE_SUBTREE;
> -			}
> -			if (note_tree_insert(t, node, n, l, type,
> -					     combine_notes_concatenate))
> -				die("Failed to load %s %s into notes tree "
> -				    "from %s",
> -				    type == PTR_TYPE_NOTE ? "note" : "subtree",
> -				    oid_to_hex(&l->key_oid), t->ref);
> +		type = PTR_TYPE_NOTE;
> +		l = (struct leaf_node *)
> +			xcalloc(1, sizeof(struct leaf_node));
> +		oidcpy(&l->key_oid, &object_oid);
> +		oidcpy(&l->val_oid, entry.oid);
> +		if (len < GIT_SHA1_RAWSZ) {
> +			if (!S_ISDIR(entry.mode) || path_len != 2)
> +				goto handle_non_note; /* not subtree */
> +			l->key_oid.hash[KEY_INDEX] = (unsigned char) len;
> +			type = PTR_TYPE_SUBTREE;
>  		}
> +		if (note_tree_insert(t, node, n, l, type,
> +				     combine_notes_concatenate))
> +			die("Failed to load %s %s into notes tree "
> +			    "from %s",
> +			    type == PTR_TYPE_NOTE ? "note" : "subtree",
> +			    oid_to_hex(&l->key_oid), t->ref);
> +
>  		continue;
>  
>  handle_non_note:
Previous: Michael HaggertyNext: Michael Haggerty
Message 14 of 23 in “Clean up notes-related code around `load_subtree()`”
  1. 00/12 Clean up notes-related code around `load_subtree()`Michael Haggerty, Aug 26, 2017
  2. 01/12 notes: make GET_NIBBLE macro more robustMichael Haggerty, Aug 26, 2017
  3. 03/12 load_subtree(): reduce the scope of some local variablesMichael Haggerty, Aug 26, 2017
  4. 04/12 load_subtree(): fix incorrect commentMichael Haggerty, Aug 26, 2017
  5. 06/12 load_subtree(): check earlier whether an internal node is a tree entryMichael Haggerty, Aug 26, 2017
  6. 08/12 get_oid_hex_segment(): return 0 on successMichael Haggerty, Aug 26, 2017
  7. 10/12 get_oid_hex_segment(): don't pad the rest of `oid`Michael Haggerty, Aug 26, 2017
  8. 11/12 hex_to_bytes(): simpler replacement for `get_oid_hex_segment()`Michael Haggerty, Aug 26, 2017
  9. 12/12 load_subtree(): declare some variables to be `size_t`Michael Haggerty, Aug 26, 2017
  10. 07/12 load_subtree(): only consider blobs to be potential notesMichael Haggerty, Aug 26, 2017
  11. 05/12 load_subtree(): separate logic for internal vs. terminal entriesMichael Haggerty, Aug 26, 2017
  12. 09/12 load_subtree(): combine some common codeMichael Haggerty, Aug 26, 2017
  13. 02/12 load_subtree(): remove unnecessary conditionalMichael Haggerty, Aug 26, 2017
  14. Junio C HamanoAug 26, 2017
  15. Michael HaggertyAug 27, 2017
  16. Michael HaggertyAug 28, 2017
  17. Junio C HamanoSep 1, 2017
  18. Johan HerlandAug 26, 2017
  19. Jeff KingSep 9, 2017
  20. Michael HaggertySep 10, 2017
  21. Jeff KingSep 10, 2017
  22. Michael HaggertySep 12, 2017
  23. Lars SchneiderSep 12, 2017

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.