Skip to content

PolyFile reads two relational operators off a string value where libmagic reads one #3565

Description

@ESultanik

Summary

StringTest.parse reads two relational operators off a string value where libmagic reads one.
A definition that writes !>ABC means, to libmagic, "not the literal four bytes >ABC". PolyFile
reads it as "not (greater than ABC)".

This is the string analogue of #3498, which PR #3528 fixed for regex.

Reproducer

$ printf '0\tstring\t!>ABC\tfound\n' > relop.magic
$ printf 'ZZZZZ' > z.bin
$ TZ=UTC ./file/src/file -b -m relop.magic z.bin
found
from polyfile.magic import MagicMatcher

matcher = MagicMatcher.parse("relop.magic")
print({str(m) for m in matcher.match(b"ZZZZZ")})
{'ASCII text, with no line terminators'}

ZZZZZ does not begin with the four bytes >ABC, so libmagic's negation succeeds. PolyFile builds
a NegatedStringTest around a StringLengthTest, finds that ZZZ sorts after ABC, and negates
that into a failure.

Cause

libmagic's parse reads exactly one character out of the relation switch and leaves the rest of
the line to getvalue (file/src/apprentice.c:2366-2416):

	case '!':
		m->reln = *l;
		++l;
		break;

StringTest.parse in polyfile/magic.py strips a leading !, then tests the remainder for a
leading > or < and builds a StringLengthTest from it, so both characters are consumed as
operators.

The same applies to !<ABC, and to !=ABC: libmagic takes the = as the first byte of the value,
while StringTest.parse strips it.

Impact

No shipped definition in magic_defs/ writes !> or !< on a string, so nothing in the corpus
reaches this. It affects hand-written definitions and any future import from upstream.

Found while checking the sibling string tests for #3557.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions