[PATCH] uclibc:fix basename modify the input path

Wangyufen wangyufen at huawei.com
Wed Sep 24 02:07:26 UTC 2014


From: Wang Yufen <wangyufen at huawei.com>

I tested basename(path), path is "///", the basename(path) returned "/",
but the input path also be modified to "/". It because in basename impl, 
"last[1] = 0;" modified the input path, I think that isn't correct. 

This patch fix this problem. 

Signed-off-by: Wang Yufen <wangyufen at huawei.com>
---
 libc/string/__xpg_basename.c |   61 +++++++++++++++++++++++++++++-------------
 1 files changed, 42 insertions(+), 19 deletions(-)

diff --git a/libc/string/__xpg_basename.c b/libc/string/__xpg_basename.c
index 2e7ade9..4ac315c 100644
--- a/libc/string/__xpg_basename.c
+++ b/libc/string/__xpg_basename.c
@@ -6,33 +6,56 @@
  */
 
 #include <libgen.h>
-
-char *__xpg_basename(register char *path)
+#include <string.h>
+char *
+__xpg_basename (char *filename)
 {
-	static const char null_or_empty[] = ".";
-	char *first;
-	register char *last;
-
-	first = (char *) null_or_empty;
+  char *p;
 
-	if (path && *path) {
-		first = path;
-		last = path - 1;
+  if (filename == NULL || filename[0] == '\0')
+    /* We return a pointer to a static string containing ".".  */
+    p = (char *) ".";
+  else
+    {
+      p = strrchr (filename, '/');
 
-		do {
-			if ((*path != '/') && (path > ++last)) {
-				last = first = path;
-			}
-		} while (*++path);
+      if (p == NULL)
+	/* There is no slash in the filename.  Return the whole string.  */
+	p = filename;
+      else
+	{
+	  if (p[1] == '\0')
+	    {
+	      /* We must remove trailing '/'.  */
+	      while (p > filename && p[-1] == '/')
+		--p;
 
-		if (*first == '/') {
-			last = first;
+	      /* Now we can be in two situations:
+		 a) the string only contains '/' characters, so we return
+		    '/'
+		 b) p points past the last component, but we have to remove
+		    the trailing slash.  */
+	      if (p > filename)
+		{
+		  *p-- = '\0';
+		  while (p > filename && p[-1] != '/')
+		    --p;
 		}
-		last[1] = 0;
+	      else
+		/* The last slash we already found is the right position
+		   to return.  */
+		while (p[1] != '\0')
+		  ++p;
+	    }
+	  else
+	    /* Go to the first character of the name.  */
+	    ++p;
 	}
+    }
 
-	return first;
+  return p;
 }
+
 #ifndef __USE_GNU
 # undef basename
 weak_alias(__xpg_basename,basename)
-- 
1.7.1




More information about the uClibc mailing list