diff options
| author | Junio C Hamano <gitster@pobox.com> | 2014-01-13 11:34:08 -0800 | 
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2014-01-13 11:34:08 -0800 | 
| commit | 540cc75f38c9787ed012fba81b2af365621b484b (patch) | |
| tree | 3747e3f22f43926aee36fe330289973b600713c4 | |
| parent | 272220ff67d7c7210047af0e3ad79b1e3df6529a (diff) | |
| parent | 7902fe03f97e2e74f95c96b8d18a7752bbb2ef6a (diff) | |
| download | git-540cc75f38c9787ed012fba81b2af365621b484b.tar.gz | |
Merge branch 'mh/shorten-unambigous-ref'
* mh/shorten-unambigous-ref:
  shorten_unambiguous_ref(): tighten up pointer arithmetic
  gen_scanf_fmt(): delete function and use snprintf() instead
  shorten_unambiguous_ref(): introduce a new local variable
| -rw-r--r-- | refs.c | 45 | 
1 files changed, 14 insertions, 31 deletions
| @@ -3334,29 +3334,6 @@ cleanup:  	return ret;  } -/* - * generate a format suitable for scanf from a ref_rev_parse_rules - * rule, that is replace the "%.*s" spec with a "%s" spec - */ -static void gen_scanf_fmt(char *scanf_fmt, const char *rule) -{ -	char *spec; - -	spec = strstr(rule, "%.*s"); -	if (!spec || strstr(spec + 4, "%.*s")) -		die("invalid rule in ref_rev_parse_rules: %s", rule); - -	/* copy all until spec */ -	strncpy(scanf_fmt, rule, spec - rule); -	scanf_fmt[spec - rule] = '\0'; -	/* copy new spec */ -	strcat(scanf_fmt, "%s"); -	/* copy remaining rule */ -	strcat(scanf_fmt, spec + 4); - -	return; -} -  char *shorten_unambiguous_ref(const char *refname, int strict)  {  	int i; @@ -3364,23 +3341,29 @@ char *shorten_unambiguous_ref(const char *refname, int strict)  	static int nr_rules;  	char *short_name; -	/* pre generate scanf formats from ref_rev_parse_rules[] */  	if (!nr_rules) { +		/* +		 * Pre-generate scanf formats from ref_rev_parse_rules[]. +		 * Generate a format suitable for scanf from a +		 * ref_rev_parse_rules rule by interpolating "%s" at the +		 * location of the "%.*s". +		 */  		size_t total_len = 0; +		size_t offset = 0;  		/* the rule list is NULL terminated, count them first */  		for (nr_rules = 0; ref_rev_parse_rules[nr_rules]; nr_rules++) -			/* no +1 because strlen("%s") < strlen("%.*s") */ -			total_len += strlen(ref_rev_parse_rules[nr_rules]); +			/* -2 for strlen("%.*s") - strlen("%s"); +1 for NUL */ +			total_len += strlen(ref_rev_parse_rules[nr_rules]) - 2 + 1;  		scanf_fmts = xmalloc(nr_rules * sizeof(char *) + total_len); -		total_len = 0; +		offset = 0;  		for (i = 0; i < nr_rules; i++) { -			scanf_fmts[i] = (char *)&scanf_fmts[nr_rules] -					+ total_len; -			gen_scanf_fmt(scanf_fmts[i], ref_rev_parse_rules[i]); -			total_len += strlen(ref_rev_parse_rules[i]); +			assert(offset < total_len); +			scanf_fmts[i] = (char *)&scanf_fmts[nr_rules] + offset; +			offset += snprintf(scanf_fmts[i], total_len - offset, +					   ref_rev_parse_rules[i], 2, "%s") + 1;  		}  	} | 
