TMSU icon indicating copy to clipboard operation
TMSU copied to clipboard

'tmsu files -p $BASEDIR $TAG` ignores path restriction

Open 0ion9 opened this issue 9 years ago • 5 comments

Command: tmsu files -p . sometag when in $BASEDIR. This applies both to 'default database' and local databases. Expected: A list of files including only files inside current directory Actual: All files tagged sometag, including those outside of . (eg. in /tmp/, /media/, /var/)

How to reproduce:

cd /tmp
tmsu init
touch foo
tmsu tag foo sometag
tmsu tag /home sometag
tmsu files -p . sometag

My guess is that you are using $BASEDIR as a default value for --path that indicates 'no restrictions', rather than a value that would be nonsensical to intentionally input like '' (0-length string).

0ion9 avatar Apr 24 '16 02:04 0ion9

Hmm, seemed to have overlooked this issue. Will take a look. Thanks.

oniony avatar Dec 01 '16 16:12 oniony

The issue is a lot more complicated than I originally imagined.

TMSU turns the path into an absolute path then into a path relative to the database root. This results in it going from '.' to '/path/to/tmp' back to '.' (as we're in the database root directory).

In order to match on the path, TMSU adds a where clause on the directory and filename of the select. A file is considered to match if the stored directory matches exactly the root-relative path calculated above ('.').

But because we need to pick up any files under the match directory, TMSU also adds an OR condition for when the directory matches the path, followed by the path separator ('/' on Unix) and the SQL wildcard '%'. Unfortunately, to calculate this string, I am using filepath.Join, which when called with the parameters of '.' and '%' results in '%', matching everything.

This issue is pretty easy to fix.

oniony avatar Mar 24 '17 21:03 oniony

However, I've noticed a second issue. If one specifies a path such as --path=/ then entries relative to the database root are not returned. TMSU is oblivious to the fact that '/' is a parent of the database root.

So, in short, I'll need to make a change to check the path specified against the database root and, if it is the database root or a parent of it then return all files relative to the database root.

oniony avatar Mar 24 '17 21:03 oniony

First issue fixed (returning files not under database root directory), second issue (not returning files under database root when parent of database root specified).

oniony avatar Mar 24 '17 21:03 oniony

Need to add integration test coverage:

Where database root is /some/path, and where files are tagged under /some, /some/path and /other:

  • --path=/ - should return all files
  • --path=/other - should return those under this dir only
  • --path=/some - should return those under /some including those under root
  • --path=/some/ - should return those under /some including those under root
  • --path=/some/path - should return those under root
  • --path=/some/path/ - should return those under root
  • --path=/some/path/under - should return those under this dir only

oniony avatar Mar 30 '17 01:03 oniony