diff mbox

uclibc:fix basename modify the input path

Message ID 1411524446-13136-1-git-send-email-wangyufen@huawei.com
State Rejected
Headers show

Commit Message

Wang Yufen Sept. 24, 2014, 2:07 a.m. UTC
From: Wang Yufen <wangyufen@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@huawei.com>
---
 libc/string/__xpg_basename.c |   61 +++++++++++++++++++++++++++++-------------
 1 files changed, 42 insertions(+), 19 deletions(-)

Comments

Wang Yufen Sept. 24, 2014, 2:46 a.m. UTC | #1
On 2014/9/24 10:07, Wangyufen wrote:
> From: Wang Yufen <wangyufen@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@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)
> 

Please ignore this patch, I'll resend later.
diff mbox

Patch

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)