Bitcoin Core  24.99.0
P2P Digital Currency
unitester.cpp
Go to the documentation of this file.
1 // Copyright 2014 BitPay Inc.
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file COPYING or https://opensource.org/licenses/mit-license.php.
4 
5 #include <univalue.h>
6 
7 #include <cassert>
8 #include <cstdio>
9 #include <string>
10 
11 #ifndef JSON_TEST_SRC
12 #error JSON_TEST_SRC must point to test source directory
13 #endif
14 
15 std::string srcdir(JSON_TEST_SRC);
16 
17 static std::string rtrim(std::string s)
18 {
19  s.erase(s.find_last_not_of(" \n\r\t")+1);
20  return s;
21 }
22 
23 static void runtest(std::string filename, const std::string& jdata)
24 {
25  std::string prefix = filename.substr(0, 4);
26 
27  bool wantPass = (prefix == "pass") || (prefix == "roun");
28  bool wantFail = (prefix == "fail");
29  bool wantRoundTrip = (prefix == "roun");
30  assert(wantPass || wantFail);
31 
32  UniValue val;
33  bool testResult = val.read(jdata);
34 
35  if (wantPass) {
36  assert(testResult == true);
37  } else {
38  assert(testResult == false);
39  }
40 
41  if (wantRoundTrip) {
42  std::string odata = val.write(0, 0);
43  assert(odata == rtrim(jdata));
44  }
45 }
46 
47 static void runtest_file(const char *filename_)
48 {
49  std::string basename(filename_);
50  std::string filename = srcdir + "/" + basename;
51  FILE *f = fopen(filename.c_str(), "r");
52  assert(f != nullptr);
53 
54  std::string jdata;
55 
56  char buf[4096];
57  while (!feof(f)) {
58  int bread = fread(buf, 1, sizeof(buf), f);
59  assert(!ferror(f));
60 
61  std::string s(buf, bread);
62  jdata += s;
63  }
64 
65  assert(!ferror(f));
66  fclose(f);
67 
68  runtest(basename, jdata);
69 }
70 
71 static const char *filenames[] = {
72  "fail10.json",
73  "fail11.json",
74  "fail12.json",
75  "fail13.json",
76  "fail14.json",
77  "fail15.json",
78  "fail16.json",
79  "fail17.json",
80  //"fail18.json", // investigate
81  "fail19.json",
82  "fail1.json",
83  "fail20.json",
84  "fail21.json",
85  "fail22.json",
86  "fail23.json",
87  "fail24.json",
88  "fail25.json",
89  "fail26.json",
90  "fail27.json",
91  "fail28.json",
92  "fail29.json",
93  "fail2.json",
94  "fail30.json",
95  "fail31.json",
96  "fail32.json",
97  "fail33.json",
98  "fail34.json",
99  "fail35.json",
100  "fail36.json",
101  "fail37.json",
102  "fail38.json", // invalid unicode: only first half of surrogate pair
103  "fail39.json", // invalid unicode: only second half of surrogate pair
104  "fail40.json", // invalid unicode: broken UTF-8
105  "fail41.json", // invalid unicode: unfinished UTF-8
106  "fail42.json", // valid json with garbage following a nul byte
107  "fail44.json", // unterminated string
108  "fail45.json", // nested beyond max depth
109  "fail3.json",
110  "fail4.json", // extra comma
111  "fail5.json",
112  "fail6.json",
113  "fail7.json",
114  "fail8.json",
115  "fail9.json", // extra comma
116  "pass1.json",
117  "pass2.json",
118  "pass3.json",
119  "pass4.json",
120  "round1.json", // round-trip test
121  "round2.json", // unicode
122  "round3.json", // bare string
123  "round4.json", // bare number
124  "round5.json", // bare true
125  "round6.json", // bare false
126  "round7.json", // bare null
127 };
128 
129 // Test \u handling
131 {
132  UniValue val;
133  bool testResult;
134  // Escaped ASCII (quote)
135  testResult = val.read("[\"\\u0022\"]");
136  assert(testResult);
137  assert(val[0].get_str() == "\"");
138  // Escaped Basic Plane character, two-byte UTF-8
139  testResult = val.read("[\"\\u0191\"]");
140  assert(testResult);
141  assert(val[0].get_str() == "\xc6\x91");
142  // Escaped Basic Plane character, three-byte UTF-8
143  testResult = val.read("[\"\\u2191\"]");
144  assert(testResult);
145  assert(val[0].get_str() == "\xe2\x86\x91");
146  // Escaped Supplementary Plane character U+1d161
147  testResult = val.read("[\"\\ud834\\udd61\"]");
148  assert(testResult);
149  assert(val[0].get_str() == "\xf0\x9d\x85\xa1");
150 }
151 
153 {
154  char buf[] = "___[1,2,3]___";
155  UniValue val;
156  assert(val.read(buf + 3, 7));
157 }
158 
159 int main (int argc, char *argv[])
160 {
161  for (const auto& f: filenames) {
162  runtest_file(f);
163  }
164 
166  no_nul_test();
167 
168  return 0;
169 }
170 
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
bool read(const char *raw, size_t len)
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:25
const char * prefix
Definition: rest.cpp:974
int main(int argc, char *argv[])
Definition: unitester.cpp:159
static const char * filenames[]
Definition: unitester.cpp:71
static std::string rtrim(std::string s)
Definition: unitester.cpp:17
void unescape_unicode_test()
Definition: unitester.cpp:130
static void runtest(std::string filename, const std::string &jdata)
Definition: unitester.cpp:23
static void runtest_file(const char *filename_)
Definition: unitester.cpp:47
void no_nul_test()
Definition: unitester.cpp:152
std::string srcdir(JSON_TEST_SRC)
assert(!tx.IsCoinBase())