@@ -29,6 +29,8 @@ struct SarifTreeDecoder::Private {
2929 void readToolInfo (TScanProps *pScanProps, const pt::ptree *toolNode);
3030
3131 std::string singleChecker = " UNKNOWN_SARIF_WARNING" ;
32+ std::string pwd;
33+ const RE reFileUrl = RE(" ^file://" );
3234 const RE reCwe = RE(" ^CWE-([0-9]+)$" );
3335 const RE reVersion = RE(" ^([0-9][0-9.]+).*$" );
3436 const RE reRuleId =
@@ -156,6 +158,22 @@ void SarifTreeDecoder::readScanProps(
156158 const pt::ptree *toolNode;
157159 if (findChildOf (&toolNode, run0, " tool" ))
158160 d->readToolInfo (pDst, toolNode);
161+
162+ // read PWD so that we can reconstruct absolute paths later on
163+ const pt::ptree *uriBase, *pwdNode, *uriNode;
164+ if (findChildOf (&uriBase, run0, " originalUriBaseIds" )
165+ && findChildOf (&pwdNode, *uriBase, " PWD" )
166+ && findChildOf (&uriNode, *pwdNode, " uri" ))
167+ {
168+ // remove the "file://" prefix
169+ const auto &pwd = uriNode->data ();
170+ d->pwd = boost::regex_replace (pwd, d->reFileUrl , " " );
171+ // FIXME: Should we check whether d->pwd begins with '/'?
172+
173+ // make sure that d->pwd ends with '/'
174+ if (!d->pwd .empty () && *d->pwd .rbegin () != ' /' )
175+ d->pwd += ' /' ;
176+ }
159177}
160178
161179void SarifTreeDecoder::readRoot (const pt::ptree *runs)
@@ -321,6 +339,32 @@ static int sarifCweFromDefNode(const pt::ptree &defNode)
321339 return 0 ;
322340}
323341
342+ static void expandRelativePaths (Defect *pDef, const std::string &pwd)
343+ {
344+ if (pwd.empty ())
345+ // no PWD info provided
346+ return ;
347+
348+ // go through all events
349+ for (DefEvent &evt : pDef->events ) {
350+ std::string &fileName = evt.fileName ;
351+ if (fileName.empty ())
352+ // no file path to expand
353+ continue ;
354+
355+ const unsigned char beginsWith = *fileName.begin ();
356+ switch (beginsWith) {
357+ case ' /' : // absolute path
358+ case ' <' : // <unknown> and the like
359+ continue ;
360+
361+ default :
362+ // prepend `pwd` to relative path
363+ fileName = pwd + fileName;
364+ }
365+ }
366+ }
367+
324368bool SarifTreeDecoder::readNode (Defect *def)
325369{
326370 // move the iterator after we get the current position
@@ -388,6 +432,7 @@ bool SarifTreeDecoder::readNode(Defect *def)
388432 if (findChildOf (&relatedLocs, defNode, " relatedLocations" ))
389433 sarifReadComments (def, *relatedLocs);
390434
435+ expandRelativePaths (def, d->pwd );
391436 d->digger .inferLangFromChecker (def);
392437 d->digger .inferToolFromChecker (def);
393438
0 commit comments