Skip to content

Commit 681cd33

Browse files
committed
Making the iterator a tad safer (tweaking the constructor so that it can throw).
1 parent 1153778 commit 681cd33

2 files changed

Lines changed: 30 additions & 19 deletions

File tree

include/simdjson/parsedjson.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,14 @@ struct ParsedJson {
8989
tape[saved_loc] |= val;
9090
}
9191

92+
struct InvalidJSON : public std::exception {
93+
const char * what () const throw () {
94+
return "JSON document is invalid";
95+
}
96+
};
97+
9298
struct iterator {
99+
// might throw InvalidJSON if ParsedJson is invalid
93100
explicit iterator(ParsedJson &pj_);
94101
~iterator();
95102

src/parsedjsoniterator.cpp

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,41 +3,45 @@
33
#include <iterator>
44

55
ParsedJson::iterator::iterator(ParsedJson &pj_) : pj(pj_), depth(0), location(0), tape_length(0), depthindex(nullptr) {
6-
if(pj.isValid()) {
7-
depthindex = new scopeindex_t[pj.depthcapacity];
8-
if(depthindex == nullptr) { return;
9-
}
10-
depthindex[0].start_of_scope = location;
11-
current_val = pj.tape[location++];
12-
current_type = (current_val >> 56);
13-
depthindex[0].scope_type = current_type;
14-
if (current_type == 'r') {
15-
tape_length = current_val & JSONVALUEMASK;
16-
if(location < tape_length) {
6+
if(!pj.isValid()) {
7+
throw InvalidJSON();
8+
}
9+
depthindex = new scopeindex_t[pj.depthcapacity];
10+
// memory allocation would throw
11+
//if(depthindex == nullptr) {
12+
// return;
13+
//}
14+
depthindex[0].start_of_scope = location;
15+
current_val = pj.tape[location++];
16+
current_type = (current_val >> 56);
17+
depthindex[0].scope_type = current_type;
18+
if (current_type == 'r') {
19+
tape_length = current_val & JSONVALUEMASK;
20+
if(location < tape_length) {
1721
current_val = pj.tape[location];
1822
current_type = (current_val >> 56);
1923
depth++;
2024
depthindex[depth].start_of_scope = location;
2125
depthindex[depth].scope_type = current_type;
2226
}
23-
}
27+
} else {
28+
// should never happen
29+
throw InvalidJSON();
2430
}
25-
}
31+
}
2632

2733
ParsedJson::iterator::~iterator() {
2834
delete[] depthindex;
2935
}
3036

3137
ParsedJson::iterator::iterator(const iterator &o):
3238
pj(o.pj), depth(o.depth), location(o.location),
33-
tape_length(o.tape_length), current_type(o.current_type),
39+
tape_length(0), current_type(o.current_type),
3440
current_val(o.current_val), depthindex(nullptr) {
3541
depthindex = new scopeindex_t[pj.depthcapacity];
36-
if(depthindex != nullptr) {
37-
memcpy(depthindex, o.depthindex, pj.depthcapacity * sizeof(depthindex[0]));
38-
} else {
39-
tape_length = 0;
40-
}
42+
// allocation might throw
43+
memcpy(depthindex, o.depthindex, pj.depthcapacity * sizeof(depthindex[0]));
44+
tape_length = o.tape_length;
4145
}
4246

4347
ParsedJson::iterator::iterator(iterator &&o):

0 commit comments

Comments
 (0)