From 0ca2ac542620a5313f29d5a1bfdc045e1f15a39a Mon Sep 17 00:00:00 2001 From: Nico Lube Date: Sun, 4 Oct 2026 02:08:52 +0200 Subject: [PATCH] fix: don't panic on .GenerationSoftware with fewer than two values Vendor and application are mandatory; shorter attributes are kept as user-defined instead of indexing past the arguments. Found by fuzzing. --- src/parser.rs | 5 ++++- tests/component_tests.rs | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/parser.rs b/src/parser.rs index 5df5332..433ff61 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1943,7 +1943,10 @@ fn parse_file_attribute(line: Chars) -> Result { args.first().map(|value| parse_ident(value)).transpose()?, )), (".CreationDate", args, 1) => Ok(FileAttribute::CreationDate(parse_date_time(args[0])?)), - (".GenerationSoftware", args, len) if len <= 3 => { + // Vendor and application are mandatory; anything shorter falls + // through to a user-defined attribute instead of indexing past the + // arguments. + (".GenerationSoftware", args, len) if (2..=3).contains(&len) => { Ok(FileAttribute::GenerationSoftware(GenerationSoftware { vendor: args[0].to_string(), application: args[1].to_string(), diff --git a/tests/component_tests.rs b/tests/component_tests.rs index 919ceea..2d6b2b1 100644 --- a/tests/component_tests.rs +++ b/tests/component_tests.rs @@ -4055,3 +4055,24 @@ fn malformed_aperture_definition() { } if type_str.eq("T") && content.eq("%ADD10T*%") )); } + +/// A `.GenerationSoftware` file attribute with fewer than the mandatory vendor and +/// application values must not panic; it is kept as a user-defined attribute. +#[test] +fn generation_software_with_one_value_does_not_panic() { + // given + logging_init(); + + let reader = gerber_to_reader("%FSLAX23Y23*%\n%MOMM*%\n%TF.GenerationSoftware,KiCad*%\nM02*\n"); + + // when + let doc = parse(reader).unwrap(); + + // then + assert!(doc.commands.iter().any(|c| matches!( + c, + Ok(Command::ExtendedCode(ExtendedCode::FileAttribute( + FileAttribute::UserDefined { name, .. } + ))) if name == ".GenerationSoftware" + ))); +}