apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wr...@apache.org
Subject cvs commit: apr/file_io/unix filepath.c
Date Mon, 02 Apr 2001 22:01:12 GMT
wrowe       01/04/02 15:01:12

  Modified:    file_io/unix filepath.c
  Log:
    Per the suggestions of Greg Stein [thanks Greg] although I took some more
    liberties with the ideas.
  
  Revision  Changes    Path
  1.3       +52 -45    apr/file_io/unix/filepath.c
  
  Index: filepath.c
  ===================================================================
  RCS file: /home/cvs/apr/file_io/unix/filepath.c,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- filepath.c	2001/03/31 11:17:13	1.2
  +++ filepath.c	2001/04/02 22:01:11	1.3
  @@ -60,6 +60,13 @@
   #include <unistd.h>
   #endif
   
  +/* Win32 malpropism that can go away once everyone believes this
  + * code is golden, and I'm not testing it anymore :-)
  + */
  +#if APR_HAVE_DIRENT_H
  +#include <dirent.h>
  +#endif
  +
   /* Any OS that requires/refuses trailing slashes should be dealt with here.
    */
   APR_DECLARE(apr_status_t) apr_filepath_get(char **defpath, apr_pool_t *p)
  @@ -105,11 +112,11 @@
                                                apr_int32_t flags,
                                                apr_pool_t *p)
   {
  -    char path[APR_PATH_MAX];
  -    apr_size_t rootlen; /* is the original rootpath len */
  -    apr_size_t newseg;  /* is the path offset to the added path */
  -    apr_size_t addseg;  /* is the path offset we are appending at */
  -    apr_size_t endseg;  /* is the end of the current segment */
  +    char path[APR_PATH_MAX]; /* isn't null term */
  +    apr_size_t rootlen; /* is the length of the src rootpath */
  +    apr_size_t keptlen; /* is the length of the retained rootpath */
  +    apr_size_t pathlen; /* is the length of the result path */
  +    apr_size_t seglen;  /* is the end of the current segment */
       apr_status_t rv;
   
       /* Treat null as an empty path.
  @@ -178,11 +185,11 @@
            * '/'s to a single leading '/' from the addpath,
            * and leave addpath at the first non-'/' character.
            */
  -        newseg = 0;
  +        keptlen = 0;
           while (addpath[0] == '/')
               ++addpath;
  -        strcpy (path, "/");
  -        addseg = 1;
  +        path[0] = '/';
  +        pathlen = 1;
       }
       else
       {
  @@ -193,39 +200,38 @@
   
           /* Base the result path on the rootpath
            */
  -        newseg = rootlen;
  +        keptlen = rootlen;
           if (rootlen >= sizeof(path))
               return APR_ENAMETOOLONG;
  -        strcpy(path, rootpath);
  +        memcpy(path, rootpath, rootlen);
           
           /* Always '/' terminate the given root path
            */
  -        if (newseg && path[newseg - 1] != '/') {
  -            if (newseg + 1 >= sizeof(path))
  +        if (keptlen && path[keptlen - 1] != '/') {
  +            if (keptlen + 1 >= sizeof(path))
                   return APR_ENAMETOOLONG;
  -            path[newseg++] = '/';
  -            path[newseg] = '\0';
  +            path[keptlen++] = '/';
           }
  -        addseg = newseg;
  +        pathlen = keptlen;
       }
   
       while (*addpath) 
       {
           /* Parse each segment, find the closing '/' 
            */
  -        endseg = 0;
  -        while (addpath[endseg] && addpath[endseg] != '/')
  -            ++endseg;
  +        seglen = 0;
  +        while (addpath[seglen] && addpath[seglen] != '/')
  +            ++seglen;
   
  -        if (endseg == 0 || (endseg == 1 && addpath[0] == '.')) 
  +        if (seglen == 0 || (seglen == 1 && addpath[0] == '.')) 
           {
               /* noop segment (/ or ./) so skip it 
                */
           }
  -        else if (endseg == 2 && addpath[0] == '.' && addpath[1] == '.')

  +        else if (seglen == 2 && addpath[0] == '.' && addpath[1] == '.')

           {
               /* backpath (../) */
  -            if (addseg == 1 && path[0] == '/') 
  +            if (pathlen == 1 && path[0] == '/') 
               {
                   /* Attempt to move above root.  Always die if the 
                    * APR_FILEPATH_SECUREROOTTEST flag is specified.
  @@ -236,10 +242,11 @@
                   /* Otherwise this is simply a noop, above root is root.
                    * Flag that rootpath was entirely replaced.
                    */
  -                newseg = 0;
  +                keptlen = 0;
               }
  -            else if (addseg == 0 || (addseg >= 3 
  -                                  && strcmp(path + addseg - 3, "../") == 0)) 
  +            else if (pathlen == 0 
  +                  || (pathlen == 3 && !memcmp(path + pathlen - 3, "../", 3))
  +                  || (pathlen  > 3 && !memcmp(path + pathlen - 4, "/../", 4)))
               {
                   /* Path is already backpathed or empty, if the
                    * APR_FILEPATH_SECUREROOTTEST.was given die now.
  @@ -249,64 +256,64 @@
   
                   /* Otherwise append another backpath.
                    */
  -                if (addseg + 3 >= sizeof(path))
  +                if (pathlen + 3 >= sizeof(path))
                       return APR_ENAMETOOLONG;
  -                strcpy(path + addseg, "../");
  -                addseg += 3;
  +                memcpy(path + pathlen, "../", 3);
  +                pathlen += 3;
               }
               else 
               {
                   /* otherwise crop the prior segment 
                    */
                   do {
  -                    --addseg;
  -                } while (addseg && path[addseg - 1] != '/');
  -                path[addseg] = '\0';
  +                    --pathlen;
  +                } while (pathlen && path[pathlen - 1] != '/');
               }
   
               /* Now test if we are above where we started and back up
  -             * the newseg offset to reflect the added/altered path.
  +             * the keptlen offset to reflect the added/altered path.
                */
  -            if (addseg < newseg) 
  +            if (pathlen < keptlen) 
               {
                   if (flags & APR_FILEPATH_SECUREROOTTEST)
                       return APR_EABOVEROOT;
  -                newseg = addseg;
  +                keptlen = pathlen;
               }
           }
           else 
           {
               /* An actual segment, append it to the destination path
                */
  -            apr_size_t i = (addpath[endseg] != '\0');
  -            if (addseg + endseg + i >= sizeof(path))
  +            apr_size_t i = (addpath[seglen] != '\0');
  +            if (pathlen + seglen + i >= sizeof(path))
                   return APR_ENAMETOOLONG;
  -            strncpy(path + addseg, addpath, endseg + i);
  -            addseg += endseg + i;
  +            memcpy(path + pathlen, addpath, seglen + i);
  +            pathlen += seglen + i;
           }
   
           /* Skip over trailing slash to the next segment
            */
  -        if (addpath[endseg])
  -            ++endseg;
  +        if (addpath[seglen])
  +            ++seglen;
   
  -        addpath += endseg;
  +        addpath += seglen;
       }
  -
  -    /* newseg will be the rootlen unless the addpath contained
  +    path[pathlen] = '\0';
  +    
  +    /* keptlen will be the rootlen unless the addpath contained
        * backpath elements.  If so, and APR_FILEPATH_NOTABOVEROOT
        * is specified (APR_FILEPATH_SECUREROOTTEST was caught above),
        * compare the original root to assure the result path is
        * still within given root path.
        */
  -    if ((flags & APR_FILEPATH_NOTABOVEROOT) && newseg < rootlen) {
  +    if ((flags & APR_FILEPATH_NOTABOVEROOT) && keptlen < rootlen) {
           if (strncmp(rootpath, path, rootlen))
               return APR_EABOVEROOT;
           if (rootpath[rootlen - 1] != '/'
                   && path[rootlen] && path[rootlen] != '/')
               return APR_EABOVEROOT;
       }
  -
  +    
       *newpath = apr_pstrdup(p, path);
  -    return (newpath ? APR_SUCCESS : APR_ENOMEM);
  +    return APR_SUCCESS;
   }
  
  
  

Mime
View raw message