From adec63371c2e6ba2167519685448629ef08b26ae Mon Sep 17 00:00:00 2001 From: David Korczynski Date: Tue, 14 Jan 2025 16:15:24 -0800 Subject: [PATCH] core: frontends: frontend_cpp: improve cfg analysis Signed-off-by: David Korczynski --- .../frontends/frontend_cpp.py | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/fuzz_introspector/frontends/frontend_cpp.py b/src/fuzz_introspector/frontends/frontend_cpp.py index 68c3900f1..4e0dc0fb4 100644 --- a/src/fuzz_introspector/frontends/frontend_cpp.py +++ b/src/fuzz_introspector/frontends/frontend_cpp.py @@ -206,6 +206,7 @@ def _extract_information(self): param_list_node = child # Handle the full name + # Extract the scope that the function is defined in logger.info('Iterating parents') tmp_root = self.root full_name = '' @@ -218,11 +219,14 @@ def _extract_information(self): full_name = new_parent.child_by_field_name( 'name').text.decode() + '::' + full_name if new_parent.type == 'namespace_definition': - full_name = new_parent.child_by_field_name( - 'name').text.decode() + '::' + full_name + # Ignore anonymous namespaces + if new_parent.child_by_field_name('name') is not None: + full_name = new_parent.child_by_field_name( + 'name').text.decode() + '::' + full_name tmp_root = new_parent logger.debug('Full function scope not from name: %s', full_name) + # Extract the name from the function declarator tmp_name = '' tmp_node = self.root.child_by_field_name('declarator') scope_to_add = '' @@ -236,6 +240,9 @@ def _extract_information(self): if tmp_node.type == 'identifier': tmp_name = tmp_node.text.decode() break + if tmp_node.type == 'field_identifier': + tmp_name = tmp_node.text.decode() + break if tmp_node.child_by_field_name( 'name') is not None and tmp_node.child_by_field_name( 'name').type == 'identifier': @@ -456,6 +463,9 @@ def _process_callsites(self, stmt: Node, var_type = '' var_type_obj = stmt.child_by_field_name('type') + if var_type_obj is None: + return [] + if var_type_obj.type == 'primitive_type' or var_type_obj.type == 'sized_type_specifier': logger.debug('Skipping.') return [] @@ -464,8 +474,11 @@ def _process_callsites(self, stmt: Node, if var_type_obj is None: return [] if var_type_obj.type == 'qualified_identifier': - var_type += var_type_obj.child_by_field_name( - 'scope').text.decode() + '::' + # logger.debug('qualified idenfitier: %s', var_type_obj.text.decode()) + if var_type_obj.child_by_field_name('scope') is not None: + var_type += var_type_obj.child_by_field_name( + 'scope').text.decode() + var_type += '::' var_type_obj = var_type_obj.child_by_field_name('name') if var_type_obj.type == 'template_type': @@ -650,10 +663,12 @@ def extract_calltree(self, """Extracts calltree string of a calltree so that FI core can use it.""" # Create calltree from a given function # Find the function in the source code + logger.debug('Extracting calltree for %s', str(function)) if not visited_functions: visited_functions = set() if not function: + logger.debug('No function') return '' if not source_code: @@ -676,6 +691,7 @@ def extract_calltree(self, logger.debug('Found no function node') func_name = function else: + logger.debug('Could not find function') return '' line_to_print = ' ' * depth @@ -689,9 +705,11 @@ def extract_calltree(self, line_to_print += '\n' if function in visited_functions or not func_node or not source_code: + logger.debug('Function visited or no function node') return line_to_print visited_functions.add(function) + logger.debug('Iterating %s callsites', len(func_node.base_callsites)) for cs, line in func_node.base_callsites: logger.debug('Callsites: %s', cs) line_to_print += self.extract_calltree(