Skip to content

Commit 50077c8

Browse files
Fix escaping bugs that currently affect the JSON formatting test on Windows. (#626)
* Fix escaping bugs that currently affect the JSON formatting test on Windows. Other escaping bugs may remain; #620 is to fix all of them. Fixes #619. * Add test of a backslash in a file path on Linux and Mac OS X. While I'm here, fix a typo in the name of json_formating.c and add `--` to its `3c` command lines.
1 parent da7b8f5 commit 50077c8

File tree

5 files changed

+56
-14
lines changed

5 files changed

+56
-14
lines changed

clang/include/clang/3C/PersistentSourceLoc.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,13 @@ class PersistentSourceLoc {
5656
return FileName < O.FileName;
5757
}
5858

59-
void print(llvm::raw_ostream &O) const {
60-
O << FileName << ":" << LineNo << ":" << ColNoS << ":" << ColNoE;
59+
std::string toString() const {
60+
return FileName + ":" + std::to_string(LineNo) + ":" +
61+
std::to_string(ColNoS) + ":" + std::to_string(ColNoE);
6162
}
6263

64+
void print(llvm::raw_ostream &O) const { O << toString(); }
65+
6366
void dump() const { print(llvm::errs()); }
6467

6568
static PersistentSourceLoc mkPSL(const clang::Decl *D,

clang/lib/3C/3CInteractiveData.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "clang/3C/3CInteractiveData.h"
14+
#include "llvm/Support/JSON.h"
1415

1516
void ConstraintsInfo::clear() {
1617
RootWildAtomsWithReason.clear();
@@ -116,11 +117,9 @@ void ConstraintsInfo::printConstraintStats(llvm::raw_ostream &O,
116117
O << "\"InSrc\":" << (InSrcWildAtoms.find(Cause) != InSrcWildAtoms.end()) << ", ";
117118
O << "\"Location\":";
118119
const PersistentSourceLoc &PSL = PtrInfo.getLocation();
119-
if (PSL.valid()) {
120-
O << "\"";
121-
PSL.print(O);
122-
O << "\"";
123-
} else
120+
if (PSL.valid())
121+
O << llvm::json::Value(PSL.toString());
122+
else
124123
O << "null";
125124
O << ", ";
126125

clang/lib/3C/ProgramInfo.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "clang/3C/ConstraintsGraph.h"
1414
#include "clang/3C/MappingVisitor.h"
1515
#include "clang/3C/Utils.h"
16+
#include "llvm/Support/JSON.h"
1617
#include <sstream>
1718

1819
using namespace clang;
@@ -66,7 +67,10 @@ void dumpStaticFuncMapJson(const ProgramInfo::StaticFunctionMapType &EMap,
6667
if (AddComma) {
6768
O << ",\n";
6869
}
69-
O << "{\"FuncName\":\"" << DefM.first << "\", \"Constraints\":[";
70+
// The `FuncName` and `FileName` field names are backwards: this is actually
71+
// the file name, hence the need to defend against special characters.
72+
O << "{\"FuncName\":" << llvm::json::Value(DefM.first)
73+
<< ", \"Constraints\":[";
7074
bool AddComma1 = false;
7175
for (const auto &J : DefM.second) {
7276
if (AddComma1) {
@@ -113,9 +117,9 @@ void ProgramInfo::dumpJson(llvm::raw_ostream &O) const {
113117
}
114118
PersistentSourceLoc L = I.first;
115119

116-
O << "{\"line\":\"";
117-
L.print(O);
118-
O << "\",\"Variables\":[";
120+
O << "{\"line\":";
121+
O << llvm::json::Value(L.toString());
122+
O << ",\"Variables\":[";
119123
I.second->dumpJson(O);
120124
O << "]}";
121125
AddComma = true;
@@ -315,7 +319,7 @@ void ProgramInfo::printStats(const std::set<std::string> &F, raw_ostream &O,
315319
if (AddComma) {
316320
O << ",\n";
317321
}
318-
O << "{\"" << I.first << "\":{";
322+
O << "{" << llvm::json::Value(I.first) << ":{";
319323
O << "\"constraints\":" << V << ",";
320324
O << "\"ptr\":" << P << ",";
321325
O << "\"ntarr\":" << Nt << ",";

clang/test/3C/json_formating.c renamed to clang/test/3C/json_formatting.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// RUN: rm -rf %t*
22
// RUN: mkdir %t.alltypes && cd %t.alltypes
3-
// RUN: 3c -base-dir=%S -alltypes -dump-stats -dump-intermediate -debug-solver %s
3+
// RUN: 3c -base-dir=%S -alltypes -dump-stats -dump-intermediate -debug-solver %s --
44
// RUN: python -c "import json, glob; [json.load(open(f)) for f in glob.glob('*.json')]"
55
// RUN: mkdir %t.noalltypes && cd %t.noalltypes
6-
// RUN: 3c -base-dir=%S -dump-stats -dump-intermediate -debug-solver %s
6+
// RUN: 3c -base-dir=%S -dump-stats -dump-intermediate -debug-solver %s --
77
// RUN: python -c "import json, glob; [json.load(open(f)) for f in glob.glob('*.json')]"
88

99
// Testing that json files output for statistics logging are well formed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Regression test for a bug in which 3C didn't escape backslashes in file paths
2+
// in its JSON output
3+
// (https://github.com/correctcomputation/checkedc-clang/issues/619). On
4+
// Windows, file paths contain backslashes as the directory separator, so the
5+
// main json_formatting.c test would catch the bug. This test catches the bug on
6+
// Linux and Mac OS X by manually creating a file with a backslash in the name
7+
// (which is an ordinary filename character on these OSes).
8+
9+
// UNSUPPORTED: system-windows
10+
11+
// We reuse json_formatting.c to ensure that we test all the same code
12+
// constructs, but we `#include` it instead of running 3c on it directly because
13+
// some code used by 3c seems to be messing with backslashes in file names on
14+
// the command line. The `#include` seems to preserve the backslash. (This is an
15+
// unusual case, so it wouldn't be surprising if 3c's behavior changes at some
16+
// point and this test breaks and we have to redesign it.)
17+
18+
// RUN: rm -rf %t*
19+
20+
// RUN: mkdir %t.alltypes && cd %t.alltypes
21+
// RUN: cp %s .
22+
// RUN: cp %S/json_formatting.c 'json\_formatting.h'
23+
// RUN: 3c -alltypes -dump-stats -dump-intermediate -debug-solver -output-dir=out.checked json_formatting_backslash.c --
24+
// RUN: python -c "import json, glob; [json.load(open(f)) for f in glob.glob('*.json')]"
25+
26+
// RUN: mkdir %t.noalltypes && cd %t.noalltypes
27+
// RUN: cp %s .
28+
// RUN: cp %S/json_formatting.c 'json\_formatting.h'
29+
// RUN: 3c -dump-stats -dump-intermediate -debug-solver -output-dir=out.checked json_formatting_backslash.c --
30+
// RUN: python -c "import json, glob; [json.load(open(f)) for f in glob.glob('*.json')]"
31+
32+
// Even though this looks like a double-quoted string, the Checked C compiler
33+
// seems to require the backslash to _not_ be escaped. We choose `\_` because it
34+
// is not a valid escape sequence in a JSON string literal (see
35+
// https://www.json.org/).
36+
#include "json\_formatting.h"

0 commit comments

Comments
 (0)