You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/05/23 01:17:33 UTC
svn commit: r1485496 - /subversion/trunk/subversion/libsvn_subr/dirent_uri.c
Author: stefan2
Date: Wed May 22 23:17:32 2013
New Revision: 1485496
URL: http://svn.apache.org/r1485496
Log:
We frequently check relative paths for being canonical. Speed that up
by minimizing the number of conditional jumps on the hot path.
* subversion/libsvn_subr/dirent_uri.c
(relpath_is_canonical): minimize number of conditions in while() loop
Modified:
subversion/trunk/subversion/libsvn_subr/dirent_uri.c
Modified: subversion/trunk/subversion/libsvn_subr/dirent_uri.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/dirent_uri.c?rev=1485496&r1=1485495&r2=1485496&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/dirent_uri.c (original)
+++ subversion/trunk/subversion/libsvn_subr/dirent_uri.c Wed May 22 23:17:32 2013
@@ -1688,7 +1688,8 @@ svn_dirent_is_canonical(const char *dire
static svn_boolean_t
relpath_is_canonical(const char *relpath)
{
- const char *ptr = relpath, *seg = relpath;
+ const char *ptr = relpath;
+ apr_size_t i, len;
/* RELPATH is canonical if it has:
* - no '.' segments
@@ -1696,36 +1697,32 @@ relpath_is_canonical(const char *relpath
* - no '//'
*/
- if (*relpath == '\0')
- return TRUE;
-
+ /* invalid beginnings */
if (*ptr == '/')
return FALSE;
- /* Now validate the rest of the path. */
- while(1)
- {
- apr_size_t seglen = ptr - seg;
-
- if (seglen == 1 && *seg == '.')
- return FALSE; /* /./ */
-
- if (*ptr == '/' && *(ptr+1) == '/')
- return FALSE; /* // */
-
- if (! *ptr && *(ptr - 1) == '/')
- return FALSE; /* foo/ */
+ if (ptr[0] == '.' && (ptr[1] == '/' || ptr[1] == '\0'))
+ return FALSE;
- if (! *ptr)
- break;
+ /* valid special cases */
+ len = strlen(ptr);
+ if (len < 2)
+ return TRUE;
- if (*ptr == '/')
- ptr++;
- seg = ptr;
+ /* invalid endings */
+ if (ptr[len-1] == '/' || (ptr[len-1] == '.' && ptr[len-2] == '/'))
+ return FALSE;
- while (*ptr && (*ptr != '/'))
- ptr++;
- }
+ /* Now validate the rest of the path. */
+ for (i = 0; i < len - 1; ++i)
+ if (ptr[i] == '/' && ptr[i+1] <= '/') /* '.' and '/' have smaller UTF-8
+ codes than most other chars */
+ {
+ if (ptr[i+1] == '/')
+ return FALSE; /* // */
+ if (ptr[i+1] == '.' && ptr[i+2] == '/')
+ return FALSE; /* /./ */
+ }
return TRUE;
}