Skip to content

Commit 1e68df9

Browse files
committed
json-writer: draft implementation of SarifTreeEncoder
Closes: #39
1 parent aba2bb8 commit 1e68df9

File tree

1 file changed

+115
-2
lines changed

1 file changed

+115
-2
lines changed

src/json-writer.cc

Lines changed: 115 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

156157
void 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

161223
void 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

166266
void 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

Comments
 (0)