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

Re: ! [PATCH/RFC] git-mailinfo: use strbuf's instead of fixed buffers

From
Lukas Sandström <lukass@etek.chalmers.se>
Date
Jul 13, 2008, 18:17 UTC
Message-ID
<487A46C5.6000503@etek.chalmers.se>
In-Reply-To
<7vy747fx9x.fsf_-_@gitster.siamese.dyndns.org>
Junio C Hamano wrote:
Show 41 quoted lines
> Lukas Sandström <lukass@etek.chalmers.se> writes:
> 
>> -static char *sanity_check(char *name, char *email)
>> +static void sanity_check(struct strbuf *out, struct strbuf *name, struct strbuf *email)
>>  {
>> -	int len = strlen(name);
>> -	if (len < 3 || len > 60)
>> -		return email;
>> -	if (strchr(name, '@') || strchr(name, '<') || strchr(name, '>'))
>> -		return email;
>> -	return name;
>> +	struct strbuf o = STRBUF_INIT;
>> +	if (name->len < 3 || name->len > 60)
>> +		strbuf_addbuf(&o, email);
>> +	if (strchr(name->buf, '@') || strchr(name->buf, '<') ||
>> +		strchr(name->buf, '>'))
>> +		strbuf_addbuf(&o, email);
>> +	strbuf_addbuf(&o, name);
>> +	strbuf_reset(out);
>> +	strbuf_addbuf(out, &o);
>> +	strbuf_release(&o);
> 
> This does not look like a correct conversion.  When name is too short or
> too long, we do not even look at name and return email straight.  Perhaps
> this would be more faithful conversion:
> 
> 	struct strbuf *src = name;
> 	if (name->len < 3 ||
>             60 < name->len ||
> 	    strchr(name->buf, '@') ||
> 	    strchr(name->buf, '<') ||
> 	    strchr(name->buf, '>'))
> 		src = email;
> 	else if (name == out)
>         	return;
> 	strbuf_reset(out);
> 	strbuf_addbuf(out, src);
> 
> It is not your fault, but sanity_check() is a grave misnomer for this
> function.  This does "get_sane_name" (i.e. we have name and email but if
> name does not look right, use email instead).
Right. I changed the name and used your implementation.
>> -static int bogus_from(char *line)
>> +static int bogus_from(const struct strbuf *line)
>>  {
[ ... ]
Show 12 quoted lines
>>  	return 1;
>>  }
> 
> Conversion looks correct but its return value does not make much sense
> (again, not your fault).  bogus_from() is given a bogus looking from line
> (it is not about checking if it is bogus), and returns 0 if we already
> have e-mail address, if the from line does not have bra-ket for grabbing
> e-mail address for, but returns 1 if we managed to get name and email
> pairs.  The inconsistency does not matter only because its sole caller
> handle_from() returns its return value, and its caller discards it.  We
> may be better off declaring this function and handle_from() as void.
> 
Done.
Show 7 quoted lines
>>  	/* The remainder is name.  It could be "John Doe <john.doe@xz>"
>>  	 * or "john.doe@xz (John Doe)", but we have whited out the
>>  	 * email part, so trim from both ends, possibly removing
>>  	 * the () pair at the end.
>>  	 */
> 
> Now, it should read "but we have removed the email part", I think.
Done.
Show 7 quoted lines
>> +	strbuf_trim(from);
>> +	if (*from->buf == '(')
>> +		strbuf_remove(&name, 0, 1);
>> +	if (*(from->buf + from->len - 1) == ')')
> 
> Can from be empty at this point before this check?
> 
Yes. Added a test for that.
Show 10 quoted lines
>> +		strbuf_setlen(from, from->len - 1);
>> +
>> +	sanity_check(&name, from, &email);
>>  	return 1;
>>  }
> 
> We used to copy the data from the argument (in_line) before munging it in
> this function, but now we are modifying it in place (from).  Does this
> upset our caller, or the original code was just doing an extra unnecessary
> copy?

No, it's ok with the current code, since when handle_from() is called, it's the last time we look at the header[i] field. I changed it to copy its argument anyway, for future-proofing.

Show 22 quoted lines
> 
>> -static int handle_header(char *line, char *data, int ofs)
>> +static void handle_header(struct strbuf **out, const struct strbuf *line)
>>  {
>> -	if (!line || !data)
>> -		return 1;
>> -
>> -	strcpy(data, line+ofs);
>> +	if (!*out) {
>> +		*out = xmalloc(sizeof(struct strbuf));
>> +		strbuf_init(*out, line->len);
>> +	} else
>> +		strbuf_reset(*out);
>>  
>> -	return 0;
>> +	strbuf_addbuf(*out, (struct strbuf *)line); /* const warning */
>>  }
> 
> I think its second parameter can safely become "const struct strbuf *";
> perhaps we should fix the definition of strbuf_addbuf() in your first
> patch?
> 
Done.
Show 20 quoted lines
>> @@ -173,180 +153,176 @@ static int slurp_attr(const char *line, const char *name, char *attr)
>>  	else
>>  		ends = "; \t";
>>  	sz = strcspn(ap, ends);
>> -	memcpy(attr, ap, sz);
>> -	attr[sz] = 0;
>> +	strbuf_add(attr, ap, sz);
>>  	return 1;
>>  }
>>  
>>  struct content_type {
>> -	char *boundary;
>> -	int boundary_len;
>> +	struct strbuf *boundary;
>>  };
>>  
>>  static struct content_type content[MAX_BOUNDARIES];
> 
> Wouldn't it make more sense to get rid of "struct content_type" altogether
> and use "struct strbuf *content[MAX_BOUNDARIES]" directly?
Sure.
I'll send a patch updated with your comments shortly.
/Lukas
Previous: Junio C HamanoNext: Lukas Sandström
Message 10 of 14 in “git-mailinfo: Fix getting the subject from the body”
  1. git-mailinfo: Fix getting the subject from the bodyLukas Sandström, Jul 10, 2008
  2. Junio C HamanoJul 12, 2008
  3. Lukas SandströmJul 12, 2008
  4. Don ZickusJul 15, 2008
  5. Lukas SandströmJul 10, 2008
  6. Junio C HamanoJul 10, 2008
  7. Add some useful functions for strbuf manipulation.Lukas Sandström, Jul 10, 2008
  8. git-mailinfo: use strbuf's instead of fixed buffersLukas Sandström, Jul 10, 2008
  9. Junio C HamanoJul 12, 2008
  10. Lukas SandströmJul 13, 2008
  11. Make some strbuf_*() struct strbuf arguments const.Lukas Sandström, Jul 13, 2008
  12. Add some useful functions for strbuf manipulation.Lukas Sandström, Jul 13, 2008
  13. git-mailinfo: use strbuf's instead of fixed buffersLukas Sandström, Jul 13, 2008
  14. Junio C HamanoJul 13, 2008

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.