diff -ur -N -x find.info findutils-4.4.0.orig/locate/locate.c findutils-4.4.0/locate/locate.c --- findutils-4.4.0.orig/locate/locate.c 2008-03-08 22:30:51.000000000 +0100 +++ findutils-4.4.0/locate/locate.c 2008-03-25 13:43:00.000000000 +0100 @@ -332,9 +332,10 @@ 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; + int prefix_len; /* The length of the prefix for relative paths. */ + int first; char *original_filename; /* The current input database entry. */ size_t pathsize; /* Amount allocated for it. */ char *munged_filename; /* path or basename(path) */ @@ -569,39 +570,21 @@ 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; - } + /* Manufacture initial count=0 for slocate database. */ + ungetc (procdata->c, procdata->fp); + procdata->c = procdata->slocatedb_format = 0; } + + if (procdata->c == LOCATEDB_ESCAPE) + procdata->count += (short)get_short (procdata->fp); + else if (procdata->c > 127) + procdata->count += procdata->c - 256; 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; - } + procdata->count += procdata->c; - if (procdata->count > procdata->len || procdata->count < 0) + if (procdata->count > procdata->len || procdata->count < procdata->prefix_len) { - /* This should not happen generally , but since we're + /* This should not happen generally, but since we're * reading in data which is outside our control, we * cannot prevent it. */ @@ -613,27 +596,48 @@ nread = locate_read_str (&procdata->original_filename, &procdata->pathsize, procdata->fp, 0, procdata->count); - if (nread < 0) + if (nread < 1) return VISIT_ABORT; procdata->c = getc (procdata->fp); - procdata->len = procdata->count + nread; - s = procdata->original_filename + procdata->len - 1; /* Move to the last char in path. */ + procdata->len = procdata->count + nread - 1; + + if (procdata->len == 0) + { + if (procdata->first) + { + /* A database with relative pathnames. + * Prepend dirname(dbfile) to all stored pathnames. + */ + extend (procdata, strlen (procdata->dbfile), 1u); + strcpy (procdata->original_filename, procdata->dbfile); + if (strcmp (procdata->original_filename, "")) + { + char *p = procdata->original_filename + + FILE_SYSTEM_PREFIX_LEN (procdata->original_filename); + p[dir_len (p)] = '\0'; + if (!strcmp (p, "") || !strcmp (p, "/")) + strcpy (p, "."); + } + procdata->prefix_len = procdata->len = procdata->count = strlen (procdata->original_filename); + procdata->first = 0; + return VISIT_REJECTED; /* Ignore this entry. */ + } + + /* This should not happen generally, but since we're + * reading in data which is outside our control, we + * cannot prevent it. + */ + error(1, 0, _("locate database `%s' is corrupt or invalid"), procdata->dbfile); + } + procdata->first = 0; + + s = procdata->original_filename + procdata->len; /* Move to the last char in path. */ assert (s[0] != '\0'); assert (s[1] == '\0'); /* Our terminator. */ assert (s[2] == '\0'); /* Added by locate_read_str. */ 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; } @@ -1086,9 +1090,8 @@ oldformat = 0; procdata.endian_state = GetwordEndianStateInitial; - procdata.len = procdata.count = 0; - procdata.slocatedb_format = 0; - procdata.itemcount = 0; + procdata.len = procdata.count = procdata.prefix_len = 0; + procdata.first = 1; procdata.dbfile = dbfile; procdata.fp = fp;