Menu

#253 Ns_NormalizePath() breaks //foo/bar paths on Windows

aolserver_v40
open-fixed
API: C (24)
5
2006-03-28
2005-03-14
No

On Windows, paths like "//foo/bar" are allowed and
sometimes necessary. AOLserver's Ns_NormalizePath() C
function incorrectly changes that path to "/foo/bar".
Tcl, on the other hand, does the right thing.

In AOLserver 4.0.10, the following test script gives
the following results on Windows and Linux:

ns_return 200 text/plain "
[ns_normalizepath
{//unixbox/vmhome/log/mysite-win-error.log}]
[file normalize
{//unixbox/vmhome/log/mysite-win-error.log}]
"

Run on Windows XP (bad):

/unixbox/vmhome/log/mysite-win-error.log
//unixbox/vmhome/log/mysite-win-error.log

Run on Linux (ok):

/unixbox/vmhome/log/mysite-win-error.log
/unixbox/vmhome/log/mysite-win-error.log

Discussion

  • Andrew Piskorski

    Logged In: YES
    user_id=43168

    I noticed this because I'm running AOLserver on Windows, but
    having AOLserver write its server log to a Linux box over
    Samba. Thus, the full path to my server log is:
    "//pinky/vmhome/log/mysite-error.log"

    When I roll the server log every night, the log roll works
    (after fixing bug #994224), but that also calls
    Ns_PurgeFiles() to delete excess old logs, which fails with
    this error:

    [14/Mar/2005:00:00:02][3996.2912][-sched-] Error: rollfile:
    failed to purge files:opendir(/pinky/vmhome/log) failed: 'No
    such file or directory'

    Of course, the problem is that from Windows there is no such
    directory as "/pinky" (1 slash), but "//pinky" (2 slashes)
    definitely does exist.

    Ns_NormalizePath() is fairly short so the simplest solution
    is probably just to fix it. But at the moment I'm not
    seeing what part eats the slash.

    Tcl already does this (and probably other stuff as well)
    correctly. However, the functionality is all in
    TclpObjNormalizePath(), which insists on having a Tcl
    interp, using Tcl_Objs, etc., no C API that could be made
    easily compatible with Ns_NormalizePath().
    TclpObjNormalizePath() is also MUCH more complicated.

     
  • Andrew Piskorski

    Logged In: YES
    user_id=43168

    Ok, I figured out a way to fix this; it's very simple. I
    created the patch like this:

    cvs diff -u -r aolserver_v40_r10 nsd/pathname.c >
    patch-bug-1162890-v40r10.txt

     
  • Andrew Piskorski

     
  • Tom Jackson

    Tom Jackson - 2005-03-14

    Logged In: YES
    user_id=661593

    On linux // is interpreted the same as /, so there is no need to remove
    the extra /, how about other Unix OS? Another thing to check is if the
    HTTP URI allows empty path segments. It probably does. AOLserver
    currently ignores the extra / in the url. Is there a problem with your
    patch if there are differences in URI/OS paths?

    I'll check the URI spec to to see what I find, AOLserver already has one
    problem with URI interpretation. I believe that each path segment is
    now allowed to have a parameter section.

     
  • Andrew Piskorski

    Logged In: YES
    user_id=43168

    TclpObjNormalizePath() is documented to modify the existing
    path in place, but Ns_NormalizePath() however does not work
    that way.

    Ns_NormalizePath() reads the path and constructs and
    entirley new one in the Ns_DString *dsPtr provided by the
    caller. Thus, my tiny little patch simply writes out one
    additional slash in the case where that makes sense - when
    the two slashes are the very beginning of the path.
    Ns_NormalizePath()'s handling of all other slashes in the
    path is unchanged by my patch.

    In the long run I think it would be much better to just use
    Tcl's implementation of many things like this. However, in
    this particular case Ns_NormalizePath() is a published
    public function so if we do decide to simply deprecate it
    entirely, it needs to be marked as such for a long time
    before actually removing it. Also, I suspect that
    Ns_NormalizePath() is used on EVERY SINGLE hit to the server
    as part of decoding URLs to file paths to be served, so it's
    speed and bug-freeness might be very important.

    There is also the broader question, of why is stuff like log
    rolling being done in C code AT ALL? Rolling the log once a
    night is obviously of no performance significance, so why
    isn't it written entirely in Tcl rather than C?

     
  • Andrew Piskorski

    Logged In: YES
    user_id=43168

    I've committed the fix in the small patch below, on the
    4.0.x branch.

     
  • Andrew Piskorski

    • assigned_to: nobody --> apiskors
    • status: open --> open-fixed
     

Log in to post a comment.

MongoDB Logo MongoDB