Fixes recursion bug in disambiguate_in(). origin/libmagic
authorRobin Luckey <rluckey@blackducksoftware.com>
Mon, 9 Apr 2012 20:50:12 +0000 (13:50 -0700)
committerRobin Luckey <rluckey@blackducksoftware.com>
Mon, 9 Apr 2012 20:50:12 +0000 (13:50 -0700)
commitfb1cc0962643aa7dbb2f87c5ed2308ce9e2cfad5
treed0361554f150972b151deb670649e0b9ca855913
parent4a4345283b347cd928e45ef4a25ca948995229b3
Fixes recursion bug in disambiguate_in().

The basic strategy of disambiguate_in() is to strip the trailing *.in
extension from the filepath, and then to disambiguate the file as if it
originally had that name. Thus, given file "foo.in", disambiguate_in()
will disambiguate "foo".

disambiguate_in() achieves this while re-using the exact same file on
disk. This is possible because a SourceFile struct has both a `filepath`
(the name we use for disambiguation purposes) and the `diskpath` (the
actual name on disk).

So disambiguate_in() instantiates a new SourceFile with a stripped
filepath, yet the same diskpath and same file contents.

The bug is that the code did this incorrectly: when assigning the
diskpath of the new SourceFile, it would mistakenly assign it the
previous SourceFile's *filepath* instead of the previous SourceFile's
diskpath.

If disambiguate_in() runs just once (when the file has just a single
*.in extension, the usual case), this mistake does not matter because
the filepath and diskpath are the same.

But if disambiguate_in() recurses on itself (when the file has multiple
*.in.in extensions), then during the second pass the filepath and
diskpath will not be equal -- they will differ by one missing *.in
extension. Thus the diskpath of the new SourceFile will refer to a
(probably) non-existent file.

The bug is hard to explain but was simple to correct.

In addition to correcting the diskpath assignment, I've fixed a memory
leak: it was possible to allocate a new SourceFile, and then immediately
return NULL, which fails to free the SourceFile. I've moved the
allocation *after* the NULL return check to avoid this.
src/detector.c
test/detect_files/foo.in.in [new file with mode: 0644]
test/unit/detector_test.h