bugGNU Octave - Bugs: bug #48105, function "glob" oddities...

 
 

bug #48105: function "glob" oddities with trailing "/"

Submitter:  None
Submitted:  Fri 03 Jun 2016 04:02:28 AM UTC
   
 
Category:  Octave Function Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Incorrect Result
Status:  Fixed Assigned to:  mtmiller
Originator Name:  Originator Email:  -email is unavailable-
Open/Closed:  * Closed Release:  * 4.0.2
Operating System:  * GNU/Linux Fixed Release:  None
Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Sun 05 Jun 2016 02:44:55 AM UTC, comment #9: 

Fixed for me as ell.  I did have to run 'make maintainer-clean' and 'bootstrap' in order to get the new glob.c copied over to libgnu.

Rik <rik5>
Group administrator
Sat 04 Jun 2016 02:24:18 AM UTC, comment #8: 

Fixed on default for me with an updated gnulib

http://hg.savannah.gnu.org/hgweb/octave/rev/96c56993e679

We typically do not update the gnulib subrepo on the stable branch, so this is fixed for the future 4.2 releases but not for any future 4.0.x bugfix releases.

Mike Miller <mtmiller>
Group Member
Sat 04 Jun 2016 01:43:11 AM UTC, comment #7: 

My mistake, testing across different versions of gnulib.

Gnulib master glob works correctly, the version that we have in Octave is buggy. This upstream commit fixed a lot of glibc issues:

http://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=36cc6c33ade715a844662cefd256f8f8fdd8a05d

I'll update our copy of gnulib and rebuild and see if this is fixed.

Mike Miller <mtmiller>
Group Member
Sat 04 Jun 2016 12:48:06 AM UTC, comment #6: 

Hm, maybe it is. I wrote a standalone C++ program to demonstrate this supposed bug with gnulib but it's not giving me the same as Octave does. If I have two files named file1 and file2, Octave's glob("f*/") returns file1 and file2. Calling gnulib::glob from a separate C++ program returns GLOB_NOMATCH.

Mike Miller <mtmiller>
Group Member
Sat 04 Jun 2016 12:03:45 AM UTC, comment #5: 

So Octave is unconditionally using gunlib's glob which is not equivalent to the shell's glob.  It seems like we should just report this upstream, and mark this as not Octave's problem.

Rik <rik5>
Group administrator
Fri 03 Jun 2016 11:02:56 PM UTC, comment #4: 

And I can confirm if I write a short C program using the standard glob function, it also fails to return a matching entry for a matched broken symlink:


#include <glob.h>
#include <stdio.h>

int
main (int argc, char *argv[])
{
  glob_t found;
  int status;
  int i;

  status = glob ("foo*", 0, NULL, &found);
  printf ("glob returns %d\n", status);

  if (status == 0)
    for (i = 0; i < found.gl_pathc; i++)
      {
        printf ("match[%d]: %s\n", i, found.gl_pathv[i]);
      }

  return 0;
}


While Perl and Python both do return matches for broken symlinks, so they are working around or reimplementing glob to fix this defect.

Mike Miller <mtmiller>
Group Member
Fri 03 Jun 2016 10:48:13 PM UTC, comment #3: 

At least on my system, the reason gnulib's own glob function is used is the following:


configure:61153: checking whether glob lists broken symlinks
configure:61192: gcc -o conftest -g -O2 -pthread -fopenmp   conftest.c -lutil -lm   >&5
configure:61192: $? = 0
configure:61192: ./conftest
configure:61192: $? = 1
configure: program exited with status 1
[…]
configure:61203: result: no


This defect means that gnulib's glob is enabled. Our logic in Octave also unconditionally uses gnulib::glob, so we are currently assuming that it's always enabled.

I didn't know what this test actually means until I looked into it. The gnulib test creates a broken symlink to a non-existent file, then calls glob with a pattern that matches the symlink. If glob returns GLOB_NOMATCH, then it is considered to be broken and gnulib's replacement function is used. I don't know the history of this or on which systems it actually works, if it's something they're trying to get rolled into glibc, etc.

Mike Miller <mtmiller>
Group Member
Fri 03 Jun 2016 09:25:35 PM UTC, comment #2: 

I'm pretty sure this is a gnulib quirk.  I created the same test directory containing two directories and two files


ls -F
d/  dir/  f  file


I then used perl, which I believe is linked against the system library version of glob, to check.


perl -de 42
@a = glob ('f*');
X a
@a = (
   0  'f'
   1  'file'
)

@b = glob ('f*/');
X b


So, the first question is why gnulib isn't just using the system version of glob that is defined in glob.h, as long as it is reasonable.  I thought gnulib was smart enough not to substitute C code where it didn't have too.  Second, since it appears to be using it's own implementation, why doesn't it have it right?

Just to check, I went and edited oct-glob.cc.  I changed


#include <glob.h>


to


#include "/usr/include/glob.h"


I then took the gnulib:: namespace decorator off the call to glob and globfree.  After re-compiling, Octave returns an empty cell array for the pattern 'f*/'.



Rik <rik5>
Group administrator
Fri 03 Jun 2016 05:39:10 AM UTC, comment #1: 

Thanks very much for the bug report. Confirmed here in the development version of Octave. This may be a bug in the underlying gnulib glob function, which wraps the system glob function in some additional logic. I think it would be worth writing a standalone test function using gnulib's glob to see if it has the same behavior, and report a bug to the gnulib project if so.

Mike Miller <mtmiller>
Group Member
Fri 03 Jun 2016 04:02:28 AM UTC, original submission:  

After trying many examples, absolute path or relative path, with or without wildcard, it is found that
if the pattern ends with "/" and has three or more characters,
the result will matches not only directories but also ordinary files.

I'm not sure whether this is a bug, although this is different from Unix shells where a pattern ends with "/" matches only directories.

Here is some examples:


octave:1>  ls -F
d/  dir/  f  file


OK with only two or less characters:

octave:2>  glob('/')
ans =
{
  [1,1] = /
}
octave:3>  glob('//')
ans =
{
  [1,1] = /
}
octave:4>  glob('./')
ans =
{
  [1,1] = ./
}
octave:5>  glob('d/')
ans =
{
  [1,1] = d/
}
octave:6>  glob('f/')
ans = {}(0x0)
octave:7>  glob('?/')
ans =
{
  [1,1] = d/
}
octave:8>  glob('*/')
ans =
{
  [1,1] = d/
  [2,1] = dir/
}


Incorrect with three or more characters:

octave:9>  glob('f*/')
ans =
{
  [1,1] = f
  [2,1] = file
}
octave:10>  glob('*?/')
ans =
{
  [1,1] = d/
  [2,1] = dir/
  [3,1] = f
  [4,1] = file
}
octave:11>  glob('./f/')
ans =
{
  [1,1] = ./f
}
octave:12>  glob('file/')
ans =
{
  [1,1] = file
}




octave:13>  ver
----------------------------------------------------------------------
GNU Octave Version: 4.0.2
GNU Octave License: GNU General Public License
Operating System: Linux 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt25-2 (2016-04-08) x86_64


Anonymous

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by mtmiller (Posted a comment)
  • -email is unavailable- added by None (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    Follow 5 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2016-06-04 mtmiller StatusIn Progress Fixed
        Open/ClosedOpen Closed
    2016-06-04 mtmiller StatusConfirmed In Progress
        Assigned toNone mtmiller
    2016-06-03 mtmiller StatusNone Confirmed

    Back to the top

    Powered by Savane 3.13-caa5.
    Corresponding source code