Fix: handle relatedLocations without physicalLocations (files)

Problem:
    The
        artifact = get(related_location, 'physicalLocation', 'artifactLocation')
    requested by
        message, artifact, region = S.get_relatedlocation_message_info(location)
    is incomplete:
        ipdb> p related_location
        {'message': {'text': 'request'}}

Fix:
    Introduce the NoFile class to propagate this and handle it where needed.

Now simply report <NoFile> as appropriate.
    For plain text output:

        RESULT: src/optionsparser/ ..
        FLOW STEP 0: <NoFile>: request
        FLOW STEP 1: <NoFile>: request_mp
        FLOW STEP 2: src/....

    For csv output:

        "result","src/optionsparser/...","116","26","116","34","`& ...` used as ..."
        "flow_step","0","<NoFile>","-1","-1","-1","-1","request"
        "flow_step","1","<NoFile>","-1","-1","-1","-1","request_mp"
        "flow_step","2","src/foo.cpp","119","97","119","104","request"
This commit is contained in:
Michael Hohn
2021-12-06 12:37:35 -08:00
committed by =Michael Hohn
parent 2c3ca3c0eb
commit 120e673424
2 changed files with 54 additions and 29 deletions

View File

@@ -8,6 +8,16 @@ MIN_PYTHON = (3, 7)
if sys.version_info < MIN_PYTHON:
sys.exit("Python %s.%s or later is required.\n" % MIN_PYTHON)
class WholeFile:
""" Special case handling: use this class for non-existent regions where the
whole file is to be used.
"""
class NoFile:
""" Special case handling: use this class for non-existent regions where the
whole file is to be used.
"""
def get_csv_writer():
""" Set up and return the default csv writer on stdout.
"""
@@ -23,19 +33,22 @@ def get_relatedlocation_message_info(related_location):
The relatedLocation typically starts from
get(sarif_struct, 'runs', [int], 'results', [int], 'relatedLocations', [int])
For a threadFlow, extract message information for a location contained in it.
When used for a threadFlow, extract message information for a location contained in it.
The location typically starts from
In this case, the location typically starts from
get(sarif_struct, 'runs', _i, 'results', _i, 'codeFlows', _i, 'threadFlows', _i, 'locations', _i)
Returns: (message, artifact, region) by default
For an empty 'physicalLocation' key, returns (message, sarif_cli.NoFile, sarif_cli.NoFile)
"""
message = get(related_location, 'message', 'text')
artifact = get(related_location, 'physicalLocation', 'artifactLocation')
region = get(related_location, 'physicalLocation', 'region')
if 'physicalLocation' in related_location:
artifact = get(related_location, 'physicalLocation', 'artifactLocation')
region = get(related_location, 'physicalLocation', 'region')
else:
artifact, region = NoFile, NoFile
return message, artifact, region
class WholeFile:
pass
def get_location_message_info(result):
""" Given one of the results, extract message information.