JavaScript is not currently enabled, but is required for full CodeSonar manual search and browse functionality.
If you are viewing this file in your hub's Web GUI, enable JavaScript in your browser: you will also need it for GUI functionality.
If you opened this file directly from disk, your browser may be directly suppressing JavaScript functionality: certain browsers perform this suppression on local files (but not files delivered by web servers) for security reasons.
| CodeSonar® 9.0p0 Hot Tips | CONFIDENTIAL | CodeSecure Inc |
This tutorial example uses the CodeSonar Plug-in API (Python) to a check for expressions of const type being cast to non-const types.
CodeSonar SaaS Note: If you want to use your own custom plug-ins with CodeSonar SaaS, contact CodeSecure support for assistance. The installation instructions provided in this page are not sufficient to make plug-ins available to SaaS analyses.
File UnsafeCast_plugin.py is reproduced below. Select any API function name to see the documentation for that function.
# Copyright (c) 2023, an unpublished work by CodeSecure, Inc. # ALL RIGHTS RESERVED # # Copyright (c) 2017-2023, an unpublished work by GrammaTech, Inc. # ALL RIGHTS RESERVED # # This software is furnished under a license and may be used and # copied only in accordance with the terms of such license and the # inclusion of the above copyright notice. This software or any # other copies thereof may not be provided or otherwise made # available to any other person. Title to and ownership of the # software is retained by CodeSecure, Inc. # # UnsafeCast_plugin.py # # A small example plug-in that reports casts from const to non-const # types. # All Python plug-ins for CodeSonar must import the cs module. import cs # badcast is a new \warning class \ defined by this plug-in. It must be # created in the top level scope. # # We do not associate any \CodeSonar mnemonics \ # or \CWE identifiers \ with the new class, as none are appropriate. badcast = cs.analysis.create_warningclass( 'Cast from const to non-const', '', 1, cs.warningclass_flags.WARNING_POINT_IS_START_POINT, cs.warning_significance.SECURITY ) # Set up the pattern in global scope. try: pat = cs.ast_pattern(''' (c:cast :2 (?e :type (c:pointer :pointed-to (?c :is-const #t))) :type (c:pointer :pointed-to (?k :is-const #f)))''') except cs.ast_pattern_compilation_error as e: print(str(e)) print(' - pattern: ', e.get_pattern()) # cs.ast_pattern_compilation_error.get_pattern() # Visitors should be at the finest granularity that is appropriate # for the check: in this case, we are checking the AST associated # with a point. @cs.point_visitor # \visitor decorator \ def check_cast(pt): # Retrieve the procedure that contains pt. proc = pt.get_procedure() # cs.point.get_procedure() # Check if the procedure was authored by the user. If not, don't # produce warnings about this code, since the user probably isn't # interested about warnings internal to library models or # synthesized procedures. if proc.get_kind() != cs.procedure_kind.USER_DEFINED: # cs.procedure.get_kind() return # Get the \normalized C/C++ AST\ associated with pt. If there isn't # one (for whatever reason), there is no point in proceeding. if pt.has_ast(cs.ast_family.C_NORMALIZED): # cs.point.has_ast() ptast = pt.get_ast(cs.ast_family.C_NORMALIZED) # cs.point.get_ast() else: print('point has no normalized C/C++ AST') return # An offending cast might be nested inside other expressions, so # we need to check every subtree of ptast against our pattern. if next((subast for subast in ptast.traverse() # cs.ast.traverse() if pat.match(subast)), # cs.ast_pattern.match() False): badcast.report(pt, 'unsafe cast') # cs.warningclass.report() return
Install the plug-in:
We have provided an extremely short example program to exercise the plug-in. You can also try building other programs into CodeSonar projects to see whether they contain these unsafe casts.
| with cl: |
codesonar analyze testcast cl /c testcast.c
|
|---|---|
| with gcc: |
codesonar analyze testcast gcc -c testcast.c
|
If you don't want to perform this check in future:
Additional sample plugins can be found at $CSONAR/codesonar/plugins/*.py where $CSONAR is your CodeSonar installation directory.