Skip to content

Commit dc954fc

Browse files
committed
fixed parsing error of && combined command
Signed-off-by: Luis Augenstein <luis.augenstein@tngtech.com>
1 parent ba0004c commit dc954fc

2 files changed

Lines changed: 23 additions & 11 deletions

File tree

sbom/lib/sbom/cmd/savedcmd_parser.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ def _parse_bindgen_command(command: str) -> list[Path]:
434434
(re.compile(r"sh (.*/)?orc_hash\.sh\b"), _parse_orc_hash_command),
435435
(re.compile(r"sh (.*/)?xen-hypercalls\.sh\b"), _parse_xen_hypercalls_command),
436436
(re.compile(r"sh (.*/)?gen_initramfs\.sh\b"), _parse_gen_initramfs_command),
437+
(re.compile(r"sh (.*/)?checkundef\.sh\b"), _parse_noop),
437438
(re.compile(r"(.*/)?vdso2c\b"), _parse_vdso2c_command),
438439
(re.compile(r"^(.*/)?mkpiggy.*?>"), _parse_mkpiggy_command),
439440
(re.compile(r"^(.*/)?relocs\b"), _parse_relocs_command),
@@ -489,7 +490,9 @@ def _unwrap_outer_parentheses(s: str) -> str:
489490
return _unwrap_outer_parentheses(s[1:-1])
490491

491492

492-
def _find_first_top_level_semicolon_position(commands: str) -> int | None:
493+
def _find_first_top_level_command_separator(
494+
commands: str, separators: list[str] = [";", "&&"]
495+
) -> tuple[int | None, int | None]:
493496
in_single_quote = False
494497
in_double_quote = False
495498
in_curly_braces = 0
@@ -516,11 +519,15 @@ def _find_first_top_level_semicolon_position(commands: str) -> int | None:
516519
if char == ")":
517520
in_braces -= 1
518521

519-
elif char == ";" and in_curly_braces == 0 and in_braces == 0:
520-
# Found top level semicolon
521-
return i
522+
if in_curly_braces > 0 or in_braces > 0:
523+
continue
524+
525+
# return found separator position and separator length
526+
for separator in separators:
527+
if commands[i : i + len(separator)] == separator:
528+
return i, len(separator)
522529

523-
return None
530+
return None, None
524531

525532

526533
def _split_commands(commands: str) -> list[str | IfBlock]:
@@ -538,11 +545,11 @@ def _split_commands(commands: str) -> list[str | IfBlock]:
538545
remaining_commands = remaining_commands.removeprefix(full_matched).lstrip("; \n")
539546
continue
540547

541-
# command until next semicolon
542-
found_semicolon_pos = _find_first_top_level_semicolon_position(remaining_commands)
543-
if found_semicolon_pos is not None:
544-
single_commands.append(remaining_commands[:found_semicolon_pos].strip())
545-
remaining_commands = remaining_commands[found_semicolon_pos + 1 :].strip()
548+
# command until next separator
549+
separator_position, separator_length = _find_first_top_level_command_separator(remaining_commands)
550+
if separator_position is not None and separator_length is not None:
551+
single_commands.append(remaining_commands[:separator_position].strip())
552+
remaining_commands = remaining_commands[separator_position + separator_length :].strip()
546553
continue
547554

548555
# single last command
@@ -554,7 +561,7 @@ def _split_commands(commands: str) -> list[str | IfBlock]:
554561

555562
def parse_commands(commands: str) -> list[Path]:
556563
"""
557-
Parses a collection of command line commands separated by semicolon and returns the combined input files required for these commands.
564+
Parses a collection of command line commands and returns the combined input files required for these commands.
558565
559566
Returns:
560567
input_files (list[str]): Input files of the commands.

sbom/lib/sbom_tests/cmd/test_savedcmd_parser.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,11 @@ def test_ld_with_at_symbol(self):
229229
expected = "@fs/efivarfs/efivarfs.mod"
230230
self._assert_parsing(cmd, expected)
231231

232+
def test_ld_if_objdump(self):
233+
cmd = """ld -o arch/x86/entry/vdso/vdso64.so.dbg -shared --hash-style=both --build-id=sha1 --eh-frame-hdr -Bsymbolic -z noexecstack -m elf_x86_64 -soname linux-vdso.so.1 --no-undefined -z max-page-size=4096 -T arch/x86/entry/vdso/vdso.lds arch/x86/entry/vdso/vdso-note.o arch/x86/entry/vdso/vclock_gettime.o arch/x86/entry/vdso/vgetcpu.o arch/x86/entry/vdso/vsgx.o && sh ./arch/x86/entry/vdso/checkundef.sh 'nm' 'arch/x86/entry/vdso/vdso64.so.dbg'; if objdump -R arch/x86/entry/vdso/vdso64.so.dbg | grep -E -h "R_X86_64_JUMP_SLOT|R_X86_64_GLOB_DAT|R_X86_64_RELATIVE| R_386_GLOB_DAT|R_386_JMP_SLOT|R_386_RELATIVE"; then (echo >&2 "arch/x86/entry/vdso/vdso64.so.dbg: dynamic relocations are not supported"; rm -f arch/x86/entry/vdso/vdso64.so.dbg; /bin/false); fi"""
234+
expected = "arch/x86/entry/vdso/vdso-note.o arch/x86/entry/vdso/vclock_gettime.o arch/x86/entry/vdso/vgetcpu.o arch/x86/entry/vdso/vsgx.o"
235+
self._assert_parsing(cmd, expected)
236+
232237
# sed command tests
233238

234239
def test_sed(self):

0 commit comments

Comments
 (0)