You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
command field type raises ValueError: No closing quotation for text with an unclosed quote #241
fieldtypes.command._split calls shlex.split(...). Text with an unbalanced quote raises ValueError: No closing quotation when the record is created. A producer that builds records
from log text then stops at that line.
Same on release 3.21 and on main (e6b58fd), with posix=False and posix=True.
Effect
The Windows Defender MPLog plugin of dissect.target builds its lowfi, threat and command
fields from log text. One line like the above ends the generator, so every later line of the
file is lost. Reproduction without a real log: four lines of the form <timestamp> x lowfi: C:\tool.exe /c <text>, the second with an unclosed quote, give 1 record
and then the exception; the other three are lost.
On a real Windows 11 Pro lab collection (NT 10.0 build 26200.8875), dissect.target 3.25.1 with
flow.record 3.21, target-query -f defender.mplog exits 1 after 2,677 records with this error. With flow.record main (e6b58fd) plus the change below, the same command exits 0 and returns 4,129 records.
A run-time version of the same fallback reports 18 values with an unclosed quote in that file. I
did not look at the content of those lines, so I do not say what causes the quote.
Proposed fix
Fall back to whitespace splitting when shlex.split raises, so the record is still created, keeps
its text and the executable is the first token:
try:
executable, *args=shlex.split(value, posix=self.__path_typeisposix_path)
exceptValueError:
# Unbalanced quote (for example a truncated log line): keep the text, split on whitespace.executable, *args=value.split()
returnexecutable.strip("'\" "), (*args,)
Behaviour of the fallback, checked on main with raw, RecordPacker pack/unpack and the JSON
packer: for an unclosed quote in the arguments (C:\tool.exe /c 'unclosed, /bin/x -c 'a b) raw equals the input, the record round-trips and the JSON output holds the original text. Like
for any command, runs of spaces collapse to one. If the quote opens the executable path
('C:\Program Files\x.exe /c y) the split is only approximate (executable C:\Program) and the
leading quote is dropped, as command already does for quoted paths; a value that is only a quote
gives an empty command. In every case no exception is raised and the rest of the file is read.
Tested on main: two new cases in test_command_windows and test_command_posix
(c:\tool.exe /c 'unclosed gives ("/c", "'unclosed")) fail with ValueError: No closing quotation without the change and pass with it; all 183 tests in tests/fieldtypes pass. If you
prefer to keep the strict behaviour by default, a keyword that selects the tolerant split would
also solve it for dissect.target.
Activity