Menu

#34 stat fails on directory ending with slash

Unstable (example)
closed-fixed
nobody
CRT (12)
5
2014-03-12
2010-12-01
Pascal Obry
No

See attached patch which fixes this issue on _stat.c and _wstat.c.

Discussion

  • Pascal Obry

    Pascal Obry - 2010-12-01

    I forgot to say that this has been tested on i686 and x86_64.

     
  • Kai Tietz

    Kai Tietz - 2010-12-01
    • status: open --> open-accepted
     
  • Kai Tietz

    Kai Tietz - 2010-12-01

    Thanks for the patch. I will give it some test. Maybe it would be good to add here a testcase for those stat function- I want to verify if the code here handles '/' and UNC correct.

    Kai

     
  • Ozkan Sezer

    Ozkan Sezer - 2010-12-01
    • status: open-accepted --> open
     
  • Ozkan Sezer

    Ozkan Sezer - 2010-12-01

    As I understand it, stat("C:\\") or stat("C:/") are OK (or, ignored by the workaround). How about stat("/") or stat("\\") ?

     
  • Pascal Obry

    Pascal Obry - 2010-12-01

    Thanks for the quick feedback. Here is a small test case I have used:

    #include <stdio.h>
    #include <sys/stat.h>

    int
    main (int argc, char **argv)
    {
    struct stat buf;
    char *f1 = "c:\\windows\\";
    char *f2 = "c:\\";
    wchar_t *wf1 = L"c:\\windows\\";
    wchar_t *wf2 = L"c:\\";

    printf ("stat(%s) = %d\n", f1, stat(f1, &buf));
    printf ("stat(%s) = %d\n", f2, stat(f2, &buf));

    wprintf (L"stat(%s) = %d\n", wf1, wstat(wf1, &buf));
    wprintf (L"stat(%s) = %d\n", wf2, wstat(wf2, &buf));
    }

     
  • Pascal Obry

    Pascal Obry - 2010-12-01

    > As I understand it, stat("C:\\") or stat("C:/") are OK (or, ignored by the
    > workaround).

    Right.

    > How about stat("/") or stat("\\") ?

    Not tested, I'll update my patch which is probably broken here.

     
  • Kai Tietz

    Kai Tietz - 2010-12-01

    I suggest the following pattern (here for _stat, but same for _wstat with different type)

    [code]
    static char*
    _mingw_no_trailing_slash (const char* _path)
    {
    int len;
    char *p;
    int start;

    p = (char*)_path;

    if (_path && *_path) {
    len = strlen (_path);

    /* Ignore X:\ */

    if ((len == 2 || len == 3) && _path[1] == ':')
    return p;
    if (len <= 1)
    return p;
    /* Check UNC \\abc\<name>\ */
    if ((_path[0] == '\\' || _path[0] == '/')
    && (_path[1] == '\\' || _path[1] == '/'))
    {
    const char *r = &_path[2];
    while (*r != 0 && *r != '\\' && *r != '/')
    ++r;
    if (*r != 0)
    ++r;
    if (*r == 0)
    return p;
    while (*r != 0 && *r != '\\' && *r != '/')
    ++r;
    if (*r != 0)
    ++r;
    if (*r == 0)
    return p;
    }

    if (_path [len - 1] == '/' || _path [len - 1] == '\\')
    {
    p = (char*)malloc (len);
    memcpy (p, _path, len - 1);
    p [len - 1] = '\0';
    }
    }

    return p;
    }
    [/code]

     

    Related

    Code: code

  • Pascal Obry

    Pascal Obry - 2010-12-01

    New patch proposed. Fixes / and \. Here is the new testcase. I have not tested the UNC path.

    <<
    #include <stdio.h>
    #include <sys/stat.h>

    int
    main (int argc, char **argv)
    {
    struct stat buf;
    char *f1 = "c:\\windows\\";
    char *f2 = "c:\\";
    char *f3 = "\\";
    char *f4 = "/";
    wchar_t *wf1 = L"c:\\windows\\";
    wchar_t *wf2 = L"c:\\";
    wchar_t *wf3 = L"\\";
    wchar_t *wf4 = L"/";

    printf ("stat(%s) = %d\n", f1, stat(f1, &buf));
    printf ("stat(%s) = %d\n", f2, stat(f2, &buf));
    printf ("stat(%s) = %d\n", f3, stat(f3, &buf));
    printf ("stat(%s) = %d\n", f4, stat(f4, &buf));

    wprintf (L"stat(%s) = %d\n", wf1, wstat(wf1, &buf));
    wprintf (L"stat(%s) = %d\n", wf2, wstat(wf2, &buf));
    wprintf (L"stat(%s) = %d\n", wf3, wstat(wf3, &buf));
    wprintf (L"stat(%s) = %d\n", wf4, wstat(wf4, &buf));
    }
    >>

     
  • Pascal Obry

    Pascal Obry - 2010-12-01

    Ktietz70,

    You code seems to be ok expect that for an UNC path without trailing slash : \\abc\<name>

    In this case the stat() routine fails whereas a dir \\abc\<name> works!

    I think that this is a minor case not worth covering.

    New patch attached.

     
  • Pascal Obry

    Pascal Obry - 2010-12-01

    New testcase here:

    <<
    #include <stdio.h>
    #include <sys/stat.h>

    void
    test (char *path)
    {
    struct stat buf;
    if (stat(path, &buf) == 0)
    printf ("OK [%s]\n", path);
    else
    printf ("ERROR [%s]\n", path);
    }

    void
    wtest (wchar_t *path)
    {
    struct stat buf;
    if (wstat(path, &buf) == 0)
    wprintf (L"OK [%s]\n", path);
    else
    wprintf (L"ERROR [%s]\n", path);
    }

    int
    main (int argc, char **argv)
    {
    test ("c:\\windows\\");
    test ("c:\\");
    test ("\\");
    test ("/");

    wtest (L"c:\\windows\\");
    wtest (L"c:\\");
    wtest (L"\\");
    wtest (L"/");
    }
    >>

    I have tested with UNC too.

     
  • Kai Tietz

    Kai Tietz - 2010-12-01

    Patch applied to trunk at revision 3832. Possibly something for our v1 branch, too.

    Thanks,
    Kai

     
  • Kai Tietz

    Kai Tietz - 2010-12-01
    • status: open --> pending-fixed
     
  • Pascal Obry

    Pascal Obry - 2010-12-01
    • status: pending-fixed --> open-fixed
     
  • Pascal Obry

    Pascal Obry - 2010-12-01

    Thanks, very responsive team!

     
  • Ozkan Sezer

    Ozkan Sezer - 2010-12-01

    The problem is that we have these same functions as inlines in sys/stat.h, too, and there is no workaround applied to them. The patch may be a candidate for the release branch if the inline situation is handled along with the static libmingwex versions.

     
  • Kai Tietz

    Kai Tietz - 2010-12-01

    Yes, good catch. So we have here two different ways to solve it. Make inlines using the path-adjustment routine from libmingwex (inlining it makes IMHO no sense here). Or remove inlines for them, which is also not a good choice IMHO. Btw the _stat64i32 (and its wide-character variant) needs same handling in my opinion. So we should make those unify-functions global and add them to sys/stat.h header.

    Kai

     
  • Kai Tietz

    Kai Tietz - 2014-03-12
    • Description has changed:

    Diff:

    --- old
    +++ new
    @@ -1,2 +1 @@
    -
     See attached patch which fixes this issue on \_stat.c and \_wstat.c.
    
    • status: open-fixed --> closed-fixed
    • Group: --> Unstable (example)
     
  • Kai Tietz

    Kai Tietz - 2014-03-12

    Issue is fixed. Therefore close thread.

     
MongoDB Logo MongoDB