2222#include " abstract-tree.hh"
2323#include " regex.hh"
2424#include " shared-string-ptree.hh"
25+ #include " version.hh"
2526
2627#include < queue>
2728
@@ -117,6 +118,73 @@ void SimpleTreeEncoder::writeTo(std::ostream &str)
117118 write_json (str, root_);
118119}
119120
121+ // SARIF 2.1.0 is documented at:
122+ // https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning/sarif-support-for-code-scanning
123+ // specification: https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/sarif-v2.1.0-os.html
124+ // validation: https://sarifweb.azurewebsites.net/Validation
125+ class SarifTreeEncoder : public AbstractTreeEncoder {
126+ public:
127+ SarifTreeEncoder ();
128+
129+ // / import supported scan properties
130+ void importScanProps (const TScanProps &) override ;
131+
132+ // / append single defect
133+ void appendDef (const Defect &) override ;
134+
135+ // / write everything to the given output stream
136+ void writeTo (std::ostream &) override ;
137+
138+ private:
139+ PTree run0_;
140+ PTree results_;
141+ };
142+
143+ SarifTreeEncoder::SarifTreeEncoder ()
144+ {
145+ // mandatory: tool/driver
146+ PTree driver;
147+ driver.put <std::string>(" name" , " csdiff" );
148+ driver.put <std::string>(" version" , CS_VERSION);
149+ driver.put <std::string>(" informationUri" ,
150+ " https://github.com/csutils/csdiff" );
151+ PTree tool;
152+ tool.put_child (" driver" , driver);
153+ run0_.put_child (" tool" , tool);
154+ }
155+
156+ void SarifTreeEncoder::importScanProps (const TScanProps &scanProps)
157+ {
158+ // TODO
159+ }
160+
161+ void SarifTreeEncoder::appendDef (const Defect &def)
162+ {
163+ // TODO
164+ }
165+
166+ void SarifTreeEncoder::writeTo (std::ostream &str)
167+ {
168+ PTree root;
169+
170+ // mandatory: schema/version
171+ root.put <std::string>(" $schema" ,
172+ " https://json.schemastore.org/sarif-2.1.0.json" );
173+ root.put <std::string>(" version" , " 2.1.0" );
174+
175+ if (!results_.empty ())
176+ // results
177+ run0_.put_child (" results" , results_);
178+
179+ // mandatory: runs
180+ PTree runs;
181+ runs.put_child (" " , run0_);
182+ root.put_child (" runs" , runs);
183+
184+ // encode as JSON
185+ write_json (str, root);
186+ }
187+
120188struct JsonWriter ::Private {
121189 std::ostream &str;
122190 std::queue<Defect> defQueue;
@@ -137,6 +205,10 @@ JsonWriter::JsonWriter(std::ostream &str, const EFileFormat format):
137205 d->encoder = new SimpleTreeEncoder;
138206 break ;
139207
208+ case FF_SARIF:
209+ d->encoder = new SarifTreeEncoder;
210+ break ;
211+
140212 default :
141213 throw std::runtime_error (" unknown output format" );
142214 }
0 commit comments