Hi,

the handling of slocate databases in locate.c is (1) unnecessarily
complicated, and (2) assumes that the second path is an extension of the
first one.  This may or may not be true.

Attached are two patches:

0002-slocate-*: adds a test case exposing the bug.

0003-slocate-*: simplifies the handling of slocate databases, also fixing
the bug.

Regards
Peter Breitenlohner <[email protected]>
From a3a36a2dc9e04b7f7c8425c1888ebb6670944018 Mon Sep 17 00:00:00 2001
From: Peter Breitenlohner <[email protected]>
Date: Mon, 3 Aug 2009 13:10:21 +0200
Subject: [PATCH 2/5] slocate: add a testcase and expose bug

Signed-off-by: Peter Breitenlohner <[email protected]>
---
 locate/testsuite/Makefile.am            |    2 ++
 locate/testsuite/locate.gnu/slocate.exp |    9 +++++++++
 locate/testsuite/locate.gnu/slocate.xo  |    3 +++
 3 files changed, 14 insertions(+), 0 deletions(-)
 create mode 100644 locate/testsuite/locate.gnu/slocate.exp
 create mode 100644 locate/testsuite/locate.gnu/slocate.xo

diff --git a/locate/testsuite/Makefile.am b/locate/testsuite/Makefile.am
index 75623bc..ca07ba8 100644
--- a/locate/testsuite/Makefile.am
+++ b/locate/testsuite/Makefile.am
@@ -17,6 +17,7 @@ locate.gnu/regex1.exp \
 locate.gnu/exists1.exp \
 locate.gnu/exists2.exp \
 locate.gnu/exists3.exp \
+locate.gnu/slocate.exp \
 locate.gnu/notexists1.exp \
 locate.gnu/notexists2.exp \
 locate.gnu/notexists3.exp \
@@ -38,6 +39,7 @@ locate.gnu/ignore_case3.xo \
 locate.gnu/exists1.xo \
 locate.gnu/exists2.xo \
 locate.gnu/exists3.xo \
+locate.gnu/slocate.xo \
 locate.gnu/notexists1.xo \
 locate.gnu/notexists2.xo \
 locate.gnu/notexists3.xo \
diff --git a/locate/testsuite/locate.gnu/slocate.exp 
b/locate/testsuite/locate.gnu/slocate.exp
new file mode 100644
index 0000000..c36d99d
--- /dev/null
+++ b/locate/testsuite/locate.gnu/slocate.exp
@@ -0,0 +1,9 @@
+# tests an slocate database, string1 (tmp/subdia) is not prefix of string2 
(tmp/subdir).
+set tmp "tmp"
+exec rm -rf $tmp
+exec mkdir $tmp
+exec touch $tmp/subdia
+exec mkdir $tmp/subdir
+exec touch $tmp/subdir/fred
+locate_start p "--changecwd=. --output=$tmp/locatedb --dbformat=slocate 
--localpaths=$tmp/subdi*" "--database=$tmp/locatedb -e subdi 2>/dev/null" {}
+
diff --git a/locate/testsuite/locate.gnu/slocate.xo 
b/locate/testsuite/locate.gnu/slocate.xo
new file mode 100644
index 0000000..ad0208c
--- /dev/null
+++ b/locate/testsuite/locate.gnu/slocate.xo
@@ -0,0 +1,3 @@
+tmp/subdia
+tmp/subdir
+tmp/subdir/fred
-- 
1.6.4

From c0b597a760ea6fc1ff80e9e2543645b781c6b3e2 Mon Sep 17 00:00:00 2001
From: Peter Breitenlohner <[email protected]>
Date: Mon, 3 Aug 2009 13:23:42 +0200
Subject: [PATCH 3/5] slocate: simplify and bug fix


Signed-off-by: Peter Breitenlohner <[email protected]>
---
 ChangeLog       |    8 ++++++++
 locate/locate.c |   50 +++++++++-----------------------------------------
 2 files changed, 17 insertions(+), 41 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index fd14c44..caffb69 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2009-08-03  Peter Breitenlohner  <[email protected]>
 
+       * locate/locate.c: Simplify handling of slocate databases.
+       Fix the bug assuming second path extends the first one.
+       * locate/testsuite/locate.gnu/slocate.{exp,xo}: New testcase
+       for slocate databse, exposing this bug.
+       * locate/testsuite/Makefile.am: Add new test case.
+
+2009-08-03  Peter Breitenlohner  <[email protected]>
+
        * doc/find.texi: Remove duplicate paragraph and fix a typo.
 
 2009-07-18  James Youngman  <[email protected]>
diff --git a/locate/locate.c b/locate/locate.c
index c01f6c2..4f2b1a7 100644
--- a/locate/locate.c
+++ b/locate/locate.c
@@ -330,7 +330,6 @@ struct regular_expression
 struct process_data
 {
   int c;                       /* An input byte.  */
-  char itemcount;              /* Indicates we're at the beginning of an 
slocate db. */
   int count; /* The length of the prefix shared with the previous database 
entry.  */
   int len;
   char *original_filename;     /* The current input database entry. */
@@ -338,7 +337,6 @@ struct process_data
   char *munged_filename;       /* path or basename(path) */
   FILE *fp;                    /* The pathname database.  */
   const char *dbfile;          /* Its name, or "<stdin>" */
-  int  slocatedb_format;       /* Allows us to cope with slocate's format 
variant */
   GetwordEndianState endian_state;
   /* for the old database format,
      the first and second characters of the most common bigrams.  */
@@ -565,37 +563,12 @@ visit_locate02_format(struct process_data *procdata, void 
*context)
   int nread;
   (void) context;
 
-  if (procdata->slocatedb_format)
-    {
-      if (procdata->itemcount == 0)
-       {
-         ungetc(procdata->c, procdata->fp);
-         procdata->count = 0;
-         procdata->len = 0;
-       }
-      else if (procdata->itemcount == 1)
-       {
-         procdata->count = procdata->len-1;
-       }
-      else
-       {
-         if (procdata->c == LOCATEDB_ESCAPE)
-           procdata->count += (short)get_short (procdata->fp);
-         else if (procdata->c > 127)
-           procdata->count += procdata->c - 256;
-         else
-           procdata->count += procdata->c;
-       }
-    }
-  else
-    {
       if (procdata->c == LOCATEDB_ESCAPE)
        procdata->count += (short)get_short (procdata->fp);
       else if (procdata->c > 127)
        procdata->count += procdata->c - 256;
       else
        procdata->count += procdata->c;
-    }
 
   if (procdata->count > procdata->len || procdata->count < 0)
     {
@@ -622,16 +595,6 @@ visit_locate02_format(struct process_data *procdata, void 
*context)
 
   procdata->munged_filename = procdata->original_filename;
 
-  if (procdata->slocatedb_format)
-    {
-      /* Don't increment indefinitely, it might overflow. */
-      if (procdata->itemcount < 6)
-       {
-         ++(procdata->itemcount);
-       }
-    }
-
-
   return VISIT_CONTINUE;
 }
 
@@ -1065,6 +1028,7 @@ search_one_database (int argc,
   struct process_data procdata;        /* Storage for data shared with 
visitors. */
   int slocate_seclevel;
   int oldformat;
+  int slocatedb_format;
   struct visitor* pvis; /* temp for determining past_pat_inspector. */
   const char *format_name;
   enum ExistenceCheckType do_check_existence;
@@ -1085,8 +1049,6 @@ search_one_database (int argc,
   oldformat = 0;
   procdata.endian_state = GetwordEndianStateInitial;
   procdata.len = procdata.count = 0;
-  procdata.slocatedb_format = 0;
-  procdata.itemcount = 0;
 
   procdata.dbfile = dbfile;
   procdata.fp = fp;
@@ -1164,13 +1126,13 @@ search_one_database (int argc,
        }
       add_visitor(visit_locate02_format, NULL);
       format_name = "slocate";
-      procdata.slocatedb_format = 1;
+      slocatedb_format = 1;
     }
   else
     {
       int nread2;
 
-      procdata.slocatedb_format = 0;
+      slocatedb_format = 0;
       extend (&procdata, sizeof(LOCATEDB_MAGIC), 0u);
       nread2 = fread (procdata.original_filename+nread, 1, sizeof 
(LOCATEDB_MAGIC)-nread,
                      procdata.fp);
@@ -1352,6 +1314,12 @@ search_one_database (int argc,
 
 
   procdata.c = getc (procdata.fp);
+  if (slocatedb_format  && (procdata.c != EOF))
+    {
+      /* Make slocate database look like GNU locate database. */
+      ungetc(procdata.c, procdata.fp);
+      procdata.c = 0;
+    }
   /* If we are searching for filename patterns, the inspector list
    * will contain an entry for each pattern for which we are searching.
    */
-- 
1.6.4

Reply via email to