@@ -136,6 +136,7 @@ class SarifTreeEncoder: public AbstractTreeEncoder {
136136 void writeTo (std::ostream &) override ;
137137
138138 private:
139+ TScanProps scanProps_;
139140 PTree run0_;
140141 PTree results_;
141142};
@@ -155,12 +156,111 @@ SarifTreeEncoder::SarifTreeEncoder()
155156
156157void SarifTreeEncoder::importScanProps (const TScanProps &scanProps)
157158{
158- // TODO
159+ scanProps_ = scanProps;
160+ }
161+
162+ static void sarifEncodeMsg (PTree *pDst, const std::string text)
163+ {
164+ PTree msg;
165+ msg.put <std::string>(" text" , text);
166+ pDst->put_child (" message" , msg);
167+ }
168+
169+ static void sarifEncodeLoc (PTree *pLoc, const Defect &def, unsigned idx)
170+ {
171+ // location ID within the result
172+ pLoc->put <unsigned >(" id" , idx);
173+
174+ const DefEvent &evt = def.events [idx];
175+
176+ // file name
177+ PTree locArt;
178+ locArt.put <std::string>(" uri" , evt.fileName );
179+ PTree locPhy;
180+ locPhy.put_child (" artifactLocation" , locArt);
181+
182+ // line/col
183+ if (evt.line ) {
184+ PTree reg;
185+ reg.put <int >(" startLine" , evt.line );
186+ if (evt.column )
187+ reg.put <int >(" startColumn" , evt.column );
188+
189+ locPhy.put_child (" region" , reg);
190+ }
191+
192+ // location
193+ pLoc->put_child (" physicalLocation" , locPhy);
194+ }
195+
196+ static void sarifEncodeEvt (PTree *pDst, const Defect &def, unsigned idx)
197+ {
198+ const DefEvent &evt = def.events [idx];
199+
200+ // location + message
201+ PTree loc;
202+ sarifEncodeLoc (&loc, def, idx);
203+ sarifEncodeMsg (&loc, evt.msg );
204+
205+ // threadFlowLocation
206+ PTree tfLoc;
207+ tfLoc.put_child (" location" , loc);
208+
209+ // verbosityLevel
210+ tfLoc.put <int >(" nestingLevel" , evt.verbosityLevel );
211+
212+ // event
213+ PTree kind;
214+ kind.put <std::string>(" " , evt.event );
215+ PTree kindList;
216+ kindList.put_child (" " , kind);
217+ tfLoc.put_child (" kinds" , kindList);
218+
219+ // append the threadFlowLocation object to the destination array
220+ pDst->push_back (std::make_pair (" " , tfLoc));
159221}
160222
161223void SarifTreeEncoder::appendDef (const Defect &def)
162224{
163- // TODO
225+ const DefEvent &keyEvt = def.events [def.keyEventIdx ];
226+ PTree result;
227+
228+ // checker (FIXME: suboptimal mapping to SARIF)
229+ const std::string ruleId = def.checker + " : " + keyEvt.event ;
230+ result.put <std::string>(" ruleId" , ruleId);
231+
232+ // key event location
233+ PTree loc;
234+ sarifEncodeLoc (&loc, def, def.keyEventIdx );
235+ PTree keyLocs;
236+ keyLocs.put_child (" " , loc);
237+ result.put_child (" locations" , keyLocs);
238+
239+ // key msg
240+ sarifEncodeMsg (&result, keyEvt.msg );
241+
242+ // other events
243+ PTree flowLocs;
244+ for (unsigned i = 0 ; i < def.events .size (); ++i)
245+ sarifEncodeEvt (&flowLocs, def, i);
246+
247+ // locations
248+ PTree tf;
249+ tf.put_child (" locations" , flowLocs);
250+
251+ // threadFlows
252+ PTree tfList;
253+ tfList.put_child (" " , tf);
254+ PTree cf;
255+ cf.put_child (" threadFlows" , tfList);
256+
257+ // codeFlows
258+ PTree cfList;
259+ cfList.put_child (" " , cf);
260+ result.put_child (" codeFlows" , cfList);
261+
262+ // append the `result` object to the `results` array
263+ results_.push_back (std::make_pair (" " , result));
164264}
165265
166266void SarifTreeEncoder::writeTo (std::ostream &str)
@@ -172,6 +272,19 @@ void SarifTreeEncoder::writeTo(std::ostream &str)
172272 " https://json.schemastore.org/sarif-2.1.0.json" );
173273 root.put <std::string>(" version" , " 2.1.0" );
174274
275+ if (!scanProps_.empty ()) {
276+ // scan props
277+ PTree props;
278+ for (TScanProps::const_reference prop : scanProps_)
279+ props.put <std::string>(prop.first , prop.second );
280+
281+ PTree extProps;
282+ extProps.put_child (" externalizedProperties" , props);
283+ PTree propsList;
284+ propsList.put_child (" " , extProps);
285+ root.put_child (" inlineExternalProperties" , propsList);
286+ }
287+
175288 if (!results_.empty ())
176289 // results
177290 run0_.put_child (" results" , results_);
0 commit comments