Protect against more function-looking macros (Fixes#502)

This commit is contained in:
Mark VanderVoord
2026-06-19 15:58:08 -04:00
parent 1ef72ca854
commit d482f56066
3 changed files with 26 additions and 0 deletions
+12
View File
@@ -259,6 +259,17 @@ class CMockHeaderParser
source.gsub!(/(\W)(?:static)(\W)/, '\1\2') unless cpp
source.gsub!(/\s*=\s*['"a-zA-Z0-9_.]+\s*/, '') # remove default value statements from argument lists
# strip macro decorator patterns that cannot be C function prototypes.
# must run after default-value removal so "= \"str\"" doesn't trigger string detection.
# neutralize string literals (never valid in C prototype args), eliminating any parentheses
# inside string content (e.g. "msg()") that would fool subsequent brace-matching.
source.gsub!(/"[^"]*"/, '""')
# strip WORD("") -- any call with a string literal arg cannot be a C function prototype
source.gsub!(/\b\w+\s*\([^)]*""[^)]*\)/, '')
# strip WORD(N...) -- any call whose first arg starts with a digit cannot be a C prototype
source.gsub!(/\b\w+\s*\(\s*\d[^)]*\)/, '')
source.gsub!(/^(?:[\w\s]*\W)?typedef\W[^;]*/m, '') # remove typedef statements
source.gsub!(/\)(\w)/, ') \1') # add space between parenthese and alphanumeric
source.gsub!(/(^|\W+)(?:#{@c_strippables.join('|')})(?=$|\W+)/, '\1') unless @c_strippables.empty? # remove known attributes slated to be stripped
@@ -636,6 +647,7 @@ class CMockHeaderParser
rettype = parsed[:type]
rettype = 'void' if @local_as_void.include?(rettype.strip)
rettype = 'void' if rettype.empty? && !(@standards + @local_as_void).include?(parsed[:name]) # all return-type tokens were stripped (e.g. bare decorator macros)
retstr = parsed[:const_ptr?] ? "#{rettype} const" : rettype
decl[:return] = { :type => rettype,
:name => 'cmock_to_return',
+3
View File
@@ -15,3 +15,6 @@
:treat_as_void:
- OSEK_TASK
- VOID_TYPE_CRAZINESS
:strippables:
- SAMPLE_EXTERN
- SAMPLE_MODE
+11
View File
@@ -116,3 +116,14 @@ inline int stuff(int num)
#define FOO_TYPE(a) foo_##a
struct FOO_TYPE(bar) { int baz; };
char b(void);
/* Here are more macros that sorta look like functions. Only sample_func is real */
#define SAMPLE_EXTERN
#define SAMPLE_MODE
#define SAMPLE_DEPRECATED(a,b)
struct struct_a;
struct struct_b;
SAMPLE_EXTERN SAMPLE_MODE SAMPLE_DEPRECATED(1.1.2, "It was bad. real bad()")
void sample_func(struct struct_a **a,
struct struct_b **b,
...);