On Mon, Mar 3, 2014 at 2:51 AM, Eric Sunshine <[email protected]> wrote:
> On Sat, Mar 1, 2014 at 7:12 AM, Nguyễn Thái Ngọc Duy <[email protected]>
> wrote:
>> We've been avoiding PATH_MAX whenever possible. This patch makes
>> get_pathname() return a strbuf and updates the callers to take
>> advantage of this. The code is simplified as we no longer need to
>> worry about buffer overflow.
>>
>> Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]>
>> ---
>> diff --git a/path.c b/path.c
>> index 24594c4..5346700 100644
>> --- a/path.c
>> +++ b/path.c
>> @@ -49,85 +60,70 @@ char *mksnpath(char *buf, size_t n, const char *fmt, ...)
>> return cleanup_path(buf);
>> }
>>
>> -static char *vsnpath(char *buf, size_t n, const char *fmt, va_list args)
>> +static void vsnpath(struct strbuf *buf, const char *fmt, va_list args)
>> {
>> const char *git_dir = get_git_dir();
>> - size_t len;
>> -
>> - len = strlen(git_dir);
>> - if (n < len + 1)
>> - goto bad;
>> - memcpy(buf, git_dir, len);
>> - if (len && !is_dir_sep(git_dir[len-1]))
>> - buf[len++] = '/';
>> - len += vsnprintf(buf + len, n - len, fmt, args);
>> - if (len >= n)
>> - goto bad;
>> - return cleanup_path(buf);
>> -bad:
>> - strlcpy(buf, bad_path, n);
>> - return buf;
>> + strbuf_addstr(buf, git_dir);
>> + if (buf->len && !is_dir_sep(buf->buf[buf->len - 1]))
>> + strbuf_addch(buf, '/');
>> + strbuf_vaddf(buf, fmt, args);
>> + strbuf_cleanup_path(buf);
>> }
>
> There's a slight semantic change here. The old code overwrote 'buf',
> but the new code appends to 'buf'. For someone familiar with
> sprintf(), or typical va_list or variadic functions there may be an
> intuitive expectation that 'buf' will be overwritten. Should this code
> be doing strbuf_reset() as its first action (or should that be the
> responsibility of the caller who is reusing 'buff')?
those callers that use get_pathname() already have strbuf reset, so
I'd say let the remaining callers reset the buffer.
>
>> char *mkpath(const char *fmt, ...)
>> {
>> va_list args;
>> - unsigned len;
>> - char *pathname = get_pathname();
>> -
>> + struct strbuf *pathname = get_pathname();
>> va_start(args, fmt);
>> - len = vsnprintf(pathname, PATH_MAX, fmt, args);
>> + strbuf_vaddf(pathname, fmt, args);
>> va_end(args);
>> - if (len >= PATH_MAX)
>> - return bad_path;
>> - return cleanup_path(pathname);
>> + return cleanup_path(pathname->buf);
>> }
>
> Prior to this change, it was possible (though probably not
> recommended) for a caller to append gunk to the returned path up to
> PATH_MAX without worrying about stomping memory. With the change, this
> is no longer true. Should the function be changed to return 'const
> char *' to enforce this restriction?
Sure. Will do (same for below)
--
Duy
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html