git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/5] Add is_absolute_path(), make_absolute_path() and normalize_path()
@ 2007-07-26  6:24 Johannes Schindelin
  2007-07-26  6:53 ` Junio C Hamano
  0 siblings, 1 reply; 5+ messages in thread
From: Johannes Schindelin @ 2007-07-26  6:24 UTC (permalink / raw)
  To: git, gitster


This patch adds convenience functions to work with absolute paths.
The function is_absolute_path() should help the efforts to integrate
the MinGW fork.

Note that make_absolute_path() returns a pointer to a static buffer.

Given a path which possibly contains "/../" and "/./", or which end
in "/", normalize_path() returns a normalized path.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 cache.h |    6 ++++++
 path.c  |   54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 0 deletions(-)

diff --git a/cache.h b/cache.h
index 53801b8..b242147 100644
--- a/cache.h
+++ b/cache.h
@@ -358,6 +358,12 @@ int git_config_perm(const char *var, const char *value);
 int adjust_shared_perm(const char *path);
 int safe_create_leading_directories(char *path);
 char *enter_repo(char *path, int strict);
+static inline int is_absolute_path(const char *path)
+{
+	return path[0] == '/';
+}
+const char *make_absolute_path(const char *path);
+char *normalize_path(char *path);
 
 /* Read and unpack a sha1 file into memory, write memory to a sha1 file */
 extern int sha1_object_info(const unsigned char *, unsigned long *);
diff --git a/path.c b/path.c
index c4ce962..92ce688 100644
--- a/path.c
+++ b/path.c
@@ -292,3 +292,57 @@ int adjust_shared_perm(const char *path)
 		return -2;
 	return 0;
 }
+
+const char *make_absolute_path(const char *path)
+{
+	static char buf[PATH_MAX];
+	const int size = sizeof(buf);
+	int len;
+
+	if (is_absolute_path(path))
+		return path;
+
+	if (!getcwd(buf, size))
+		die ("Could not get current working directory");
+	if (!strcmp(path, "."))
+		return buf;
+
+	len = strlen(buf);
+	if (snprintf(buf + len, size - len, "/%s", path) > size - 1)
+		die ("Could not make absolute path from '%s'", path);
+	return normalize_path(buf);
+}
+
+/* strip out .. and . */
+char *normalize_path(char *path)
+{
+	int i, j;
+
+	for (i = 0, j = 0; path[i]; i++, j++) {
+		if (path[i] == '.') {
+			if (path[i + 1] == '/') {
+				i++; j--;
+				continue;
+			}
+			if (path[i + 1] == '.' && (path[i + 2] == '/' ||
+						!path[i + 2])) {
+				i += 1 + !!path[i + 2];
+				j--;
+				while (j > 0 && path[--j] != '/')
+					; /* do nothing */
+				continue;
+			}
+		}
+		for (; path[i + 1]; i++, j++) {
+			path[j] = path[i];
+			if (path[i] == '/')
+				break;
+		}
+		path[j] = path[i];
+	}
+	if (j > 0 && path[j - 1] == '/')
+		j--;
+	path[j] = '\0';
+
+	return path;
+}
-- 
1.5.3.rc2.42.gda8d-dirty

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/5] Add is_absolute_path(), make_absolute_path() and normalize_path()
  2007-07-26  6:24 [PATCH 1/5] Add is_absolute_path(), make_absolute_path() and normalize_path() Johannes Schindelin
@ 2007-07-26  6:53 ` Junio C Hamano
  2007-07-26 13:58   ` Johannes Schindelin
  0 siblings, 1 reply; 5+ messages in thread
From: Junio C Hamano @ 2007-07-26  6:53 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git, gitster

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> +/* strip out .. and . */
> +char *normalize_path(char *path)
> +{

This always makes one worry what should happen when foo/../bar
is _not_ bar in reality (i.e. foo is symlink to a directory
elsewhere).

It depends on what kind of "path" you feed to the function (and
its caller, make_absolute_path()).  If you always feed a path
from the index (or a path obtained by recursively reading a
tree), it is Ok.  If it is arbitrary path obtained from the user
or the filesystem, it is not.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/5] Add is_absolute_path(), make_absolute_path() and normalize_path()
  2007-07-26  6:53 ` Junio C Hamano
@ 2007-07-26 13:58   ` Johannes Schindelin
  2007-07-26 18:46     ` Junio C Hamano
  0 siblings, 1 reply; 5+ messages in thread
From: Johannes Schindelin @ 2007-07-26 13:58 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Hi,

On Wed, 25 Jul 2007, Junio C Hamano wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > +/* strip out .. and . */
> > +char *normalize_path(char *path)
> > +{
> 
> This always makes one worry what should happen when foo/../bar
> is _not_ bar in reality (i.e. foo is symlink to a directory
> elsewhere).
> 
> It depends on what kind of "path" you feed to the function (and
> its caller, make_absolute_path()).  If you always feed a path
> >from the index (or a path obtained by recursively reading a
> tree), it is Ok.  If it is arbitrary path obtained from the user
> or the filesystem, it is not.

Agree.  Maybe a comment above the function, like

	/*
	 * The function normalize_path() converts ".." and "." names in 
	 * the given path so that "foo/../bar/./" will come out as "bar".
	 *
	 * Note: normalize_path() does not follow symlinks, so if "foo" is
	 * a symlink in the example above, the result will not work as 
	 * expected.
	 */

Hmm?

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/5] Add is_absolute_path(), make_absolute_path() and normalize_path()
  2007-07-26 13:58   ` Johannes Schindelin
@ 2007-07-26 18:46     ` Junio C Hamano
  2007-07-26 19:02       ` Johannes Schindelin
  0 siblings, 1 reply; 5+ messages in thread
From: Junio C Hamano @ 2007-07-26 18:46 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> Agree.  Maybe a comment above the function, like
>
> 	/*
> 	 * The function normalize_path() converts ".." and "." names in 
> 	 * the given path so that "foo/../bar/./" will come out as "bar".
> 	 *
> 	 * Note: normalize_path() does not follow symlinks, so if "foo" is
> 	 * a symlink in the example above, the result will not work as 
> 	 * expected.
> 	 */
>
> Hmm?

That comment only states the obvious and does not give a clue to
the callers when it should not be used, I am afraid.  For
example, paths taken out of index or recursively reading trees
are Ok because there will not be ".." and "." in them.  Making a
path given by the user relative to the cwd by prepending what is
returned by setup_git_directory() may or may not be safe,
depending on how setup_git_directory() does things (I think the
original one is safe; I am reasonably sure with the current one
when GIT_WORK_TREE is not in use; I do not know when that
environment variable is there with the current code with or
without your patch series).

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/5] Add is_absolute_path(), make_absolute_path() and normalize_path()
  2007-07-26 18:46     ` Junio C Hamano
@ 2007-07-26 19:02       ` Johannes Schindelin
  0 siblings, 0 replies; 5+ messages in thread
From: Johannes Schindelin @ 2007-07-26 19:02 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Hi,

On Thu, 26 Jul 2007, Junio C Hamano wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > Agree.  Maybe a comment above the function, like
> >
> > 	/*
> > 	 * The function normalize_path() converts ".." and "." names in 
> > 	 * the given path so that "foo/../bar/./" will come out as "bar".
> > 	 *
> > 	 * Note: normalize_path() does not follow symlinks, so if "foo" is
> > 	 * a symlink in the example above, the result will not work as 
> > 	 * expected.
> > 	 */
> >
> > Hmm?
> 
> That comment only states the obvious and does not give a clue to
> the callers when it should not be used, I am afraid.

I am afraid, that it was unobvious enough to yours truly to forget about 
that when writing the patch.

> For example, paths taken out of index or recursively reading trees are 
> Ok because there will not be ".." and "." in them.  Making a path given 
> by the user relative to the cwd by prepending what is returned by 
> setup_git_directory() may or may not be safe, depending on how 
> setup_git_directory() does things (I think the original one is safe; I 
> am reasonably sure with the current one when GIT_WORK_TREE is not in 
> use; I do not know when that environment variable is there with the 
> current code with or without your patch series).

I am afraid that already GIT_DIR can contain symlinks, and is not checked 
by setup_git_env().

So I think some concrete comment is needed in _addition_:

	get_git_dir() is not safe, and therefore git_path(), too.

Hmm.

Maybe the easiest way _is_ to getcwd(); chdir() getcwd(); chdir(back); 
Ugly.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2007-07-26 19:02 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-07-26  6:24 [PATCH 1/5] Add is_absolute_path(), make_absolute_path() and normalize_path() Johannes Schindelin
2007-07-26  6:53 ` Junio C Hamano
2007-07-26 13:58   ` Johannes Schindelin
2007-07-26 18:46     ` Junio C Hamano
2007-07-26 19:02       ` Johannes Schindelin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).