diff --git a/lib/ceedling/preprocessinator_extractor.rb b/lib/ceedling/preprocessinator_extractor.rb index c95ee9048..647f66f94 100644 --- a/lib/ceedling/preprocessinator_extractor.rb +++ b/lib/ceedling/preprocessinator_extractor.rb @@ -8,6 +8,7 @@ require 'ceedling/constants' require 'ceedling/encodinator' require 'ceedling/parsing_parcels' +require 'stringio' class PreprocessinatorExtractor @@ -80,6 +81,10 @@ class PreprocessinatorExtractor # `input` must have the interface of IO -- StringIO for testing or File in typical use def extract_file_as_array_from_expansion(input, filepath) + # Strip null bytes that GCC -E may embed in preprocessed output. + # Null bytes cause encoding errors in downstream line processing. + content = input.read.to_s.gsub("\0", "") + input = StringIO.new(content) ## ## Iterate through all lines and alternate between extract and ignore modes. diff --git a/lib/ceedling/system_wrapper.rb b/lib/ceedling/system_wrapper.rb index cc8e61230..aa52a2404 100644 --- a/lib/ceedling/system_wrapper.rb +++ b/lib/ceedling/system_wrapper.rb @@ -75,6 +75,12 @@ def shell_capture3(command:, boom:false) stdout, stderr, status = Open3.capture3(command) + # Strip null bytes that some tools (e.g. GCC -H / -E) may inject into output. + # Null bytes cause ArgumentError ("string contains null byte") in downstream + # processing such as file path operations and YAML parsing. + stdout = stdout.to_s.gsub("\0", "") + stderr = stderr.to_s.gsub("\0", "") + # If boom, then capture the actual exit code. # Otherwise, leave it as zero as though execution succeeded. exit_code = status.exitstatus.freeze if boom and !status.nil? @@ -87,7 +93,7 @@ def shell_capture3(command:, boom:false) output: (stdout + stderr).to_s.freeze, # Individual streams for detailed logging - stdout: stdout.freeze, #TODO PROBABLY DROP THESE TOO + stdout: stdout.freeze, stderr: stderr.freeze, # Relay full Process::Status diff --git a/lib/ceedling/yaml_wrapper.rb b/lib/ceedling/yaml_wrapper.rb index ad434ca65..7358416a0 100644 --- a/lib/ceedling/yaml_wrapper.rb +++ b/lib/ceedling/yaml_wrapper.rb @@ -14,10 +14,14 @@ class YamlWrapper def load(filepath) source = ERB.new(File.read(filepath)).result begin - return YAML.load(source, aliases: true) + result = YAML.load(source, aliases: true) rescue ArgumentError - return YAML.load(source) + result = YAML.load(source) end + # YAML.load("") returns false in Ruby, not nil or []. + # Callers typically check `result.nil? || result.empty?` which raises + # NoMethodError on false. Return [] for empty/false results instead. + result == false ? [] : result end def load_string(source) diff --git a/vendor/unity b/vendor/unity index eb79bce1b..54fb72f50 160000 --- a/vendor/unity +++ b/vendor/unity @@ -1 +1 @@ -Subproject commit eb79bce1b5b242ff580ccc99d8d4660625e8ffa9 +Subproject commit 54fb72f5080f5bd30e94180fefba8b1fb54fcc5c