Subject: Re: [RFH/PATCH] prefix_path(): disallow absolute paths

From: Johannes Sixt <[email-masked]>
Date: Tue, 29 Jan 2008 08:20:14 +0100

Junio C Hamano schrieb:
> +static int sanitary_path_copy(char *dst, const char *src)
>  {
> -	const char *orig = path;
> +	char *dst0 = dst;
> +
> +	if (*src == '/') {
> +		*dst++ = '/';
> +		while (*src == '/')
> +			src++;
> +	}

Advance notice: In this function, tests of the kind *src == '/' need to be
turned into is_dir_sep(*src) when we port to Windows.

> +		/* copy up to the next '/', and eat all '/' */
> +		while ((c = *src++) != '\0' && c != '/')
> +			*dst++ = c;
>  		if (c == '/') {
> -			path += 2;
> -			continue;
> -		}
> -		if (c != '.')
> +			*dst++ = c;

			*dst++ = '/';

will be needed on Windows to sanitize all is_dir_sep(c) to '/'.

> +			while (c == '/')
> +				c = *src++;
> +			src--;
> +		} else if (!c)
>  			break;
...
> +const char *prefix_path(const char *prefix, int len, const char *path)
> +{
> +	const char *orig = path;
> +	char *sanitized = xmalloc(len + strlen(path) + 1);
> +	if (*orig == '/')

	if (is_absolute_path(*orig))

> +		strcpy(sanitized, path);
> +	else {
> +		if (len)
> +			memcpy(sanitized, prefix, len);
> +		strcpy(sanitized + len, path);		
>  	}
> -	return path;
> +	if (sanitary_path_copy(sanitized, sanitized))
> +		goto error_out;
> +	if (*orig == '/') {

Ditto.

> +		const char *work_tree = get_git_work_tree();
> +		size_t len = strlen(work_tree);
> +		if (strncmp(sanitized, work_tree, len) ||
> +		    (sanitized[len] != '\0' && sanitized[len] != '/')) {
> +		error_out:
> +			error("'%s' is outside repository", orig);
> +			free(sanitized);
> +			return NULL;
> +		}
> +	}
> +	return sanitized;
>  }

I appreciate this new sanitary_copy_path() because I expect that we will
need at least one less #ifdef __MINGW32__/#endif compared to our current
Windows port.

-- Hannes