Skip to content

Commit

Permalink
add check to prevent sizeof(void) generation
Browse files Browse the repository at this point in the history
  • Loading branch information
Hannes103 committed Aug 23, 2023
1 parent a3a48e8 commit 7afe34b
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 1 deletion.
15 changes: 14 additions & 1 deletion lib/cmock_generator_plugin_return_thru_ptr.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class CMockGeneratorPluginReturnThruPtr
def initialize(_config, utils)
@utils = utils
@priority = 9
@config = _config
end

def instance_typedefs(function)
Expand All @@ -19,6 +20,17 @@ def instance_typedefs(function)
lines
end

def is_void_pointer(type)

# returns true if the provided type is a void, or is supposed to be treated as void
if( type.downcase() == "void" )
return true
else
return @config.respond_to?(:treat_as_void) ? @config.treat_as_void.include?(type) : false
end
end
private :is_void_pointer

def mock_function_declarations(function)
lines = ''
function[:args].each do |arg|
Expand All @@ -27,7 +39,8 @@ def mock_function_declarations(function)
lines << "#define #{function[:name]}_ReturnThruPtr_#{arg[:name]}(#{arg[:name]})"
# If the pointer type actually contains an asterisk, we can do sizeof the type (super safe), otherwise
# we need to do a sizeof the dereferenced pointer (which could be a problem if give the wrong size
lines << if arg[:type][-1] == '*'
# however if its a void pointer we are given then we have to use the provided parameter name because sizeof(void) is UB.
lines << if (arg[:type][-1] == '*') && (false == is_void_pointer(arg[:type][0..-2]))
" #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, sizeof(#{arg[:type][0..-2]}))\n"
else
" #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, sizeof(*#{arg[:name]}))\n"
Expand Down
42 changes: 42 additions & 0 deletions test/unit/cmock_generator_plugin_return_thru_ptr_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,18 @@
:return => test_return[:void],
:contains_ptr? => true }

@void_ptr_func = {:name => "Spruce",
:args => [{ :type => "void*",
:name => "pork",
:ptr? => true,
},
{ :type => "MY_FANCY_VOID*",
:name => "salad",
:ptr? => true,
}],
:return => test_return[:void],
:contains_ptr? => true }

#no strict ordering
@cmock_generator_plugin_return_thru_ptr = CMockGeneratorPluginReturnThruPtr.new(@config, @utils)
end
Expand All @@ -56,6 +68,13 @@ def complex_func_expect
@utils.expect :ptr_or_str?, true, ['int*']
end

def void_ptr_func_expect
@utils.expect :ptr_or_str?, true, ['void*']
@utils.expect :ptr_or_str?, true, ['MY_FANCY_VOID*']

@config.expect :treat_as_void, ['MY_FANCY_VOID']
end

it "have set up internal priority correctly on init" do
assert_equal(9, @cmock_generator_plugin_return_thru_ptr.priority)
end
Expand Down Expand Up @@ -100,6 +119,29 @@ def complex_func_expect
assert_equal(expected, returned)
end

it "add a mock function declaration with sizeof(<name>) for void pointer arguments" do
void_ptr_func_expect();

expected =
"#define Spruce_ReturnThruPtr_pork(pork)" +
" Spruce_CMockReturnMemThruPtr_pork(__LINE__, pork, sizeof(*pork))\n" +
"#define Spruce_ReturnArrayThruPtr_pork(pork, cmock_len)" +
" Spruce_CMockReturnMemThruPtr_pork(__LINE__, pork, cmock_len * sizeof(*pork))\n" +
"#define Spruce_ReturnMemThruPtr_pork(pork, cmock_size)" +
" Spruce_CMockReturnMemThruPtr_pork(__LINE__, pork, cmock_size)\n" +
"void Spruce_CMockReturnMemThruPtr_pork(UNITY_LINE_TYPE cmock_line, void* pork, size_t cmock_size);\n" +
"#define Spruce_ReturnThruPtr_salad(salad)" +
" Spruce_CMockReturnMemThruPtr_salad(__LINE__, salad, sizeof(*salad))\n" +
"#define Spruce_ReturnArrayThruPtr_salad(salad, cmock_len)" +
" Spruce_CMockReturnMemThruPtr_salad(__LINE__, salad, cmock_len * sizeof(*salad))\n" +
"#define Spruce_ReturnMemThruPtr_salad(salad, cmock_size)" +
" Spruce_CMockReturnMemThruPtr_salad(__LINE__, salad, cmock_size)\n" +
"void Spruce_CMockReturnMemThruPtr_salad(UNITY_LINE_TYPE cmock_line, MY_FANCY_VOID* salad, size_t cmock_size);\n"

returned = @cmock_generator_plugin_return_thru_ptr.mock_function_declarations(@void_ptr_func)
assert_equal(expected, returned)
end

it "add mock interfaces only for non-const pointer arguments" do
complex_func_expect();

Expand Down

0 comments on commit 7afe34b

Please sign in to comment.