Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 03217c3

Browse files
authored
Merge pull request #410 from liggitt/stack
Limit nesting depth
2 parents 908eaed + eec2489 commit 03217c3

File tree

7 files changed

+361
-6
lines changed

7 files changed

+361
-6
lines changed

‎iter.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ type Iterator struct {
7474
buf []byte
7575
head int
7676
tail int
77+
depth int
7778
captureStartedAt int
7879
captured []byte
7980
Error error
@@ -88,6 +89,7 @@ func NewIterator(cfg API) *Iterator {
8889
buf: nil,
8990
head: 0,
9091
tail: 0,
92+
depth: 0,
9193
}
9294
}
9395

@@ -99,6 +101,7 @@ func Parse(cfg API, reader io.Reader, bufSize int) *Iterator {
99101
buf: make([]byte, bufSize),
100102
head: 0,
101103
tail: 0,
104+
depth: 0,
102105
}
103106
}
104107

@@ -110,6 +113,7 @@ func ParseBytes(cfg API, input []byte) *Iterator {
110113
buf: input,
111114
head: 0,
112115
tail: len(input),
116+
depth: 0,
113117
}
114118
}
115119

@@ -128,6 +132,7 @@ func (iter *Iterator) Reset(reader io.Reader) *Iterator {
128132
iter.reader = reader
129133
iter.head = 0
130134
iter.tail = 0
135+
iter.depth = 0
131136
return iter
132137
}
133138

@@ -137,6 +142,7 @@ func (iter *Iterator) ResetBytes(input []byte) *Iterator {
137142
iter.buf = input
138143
iter.head = 0
139144
iter.tail = len(input)
145+
iter.depth = 0
140146
return iter
141147
}
142148

@@ -320,3 +326,24 @@ func (iter *Iterator) Read() interface{} {
320326
return nil
321327
}
322328
}
329+
330+
// limit maximum depth of nesting, as allowed by https://tools.ietf.org/html/rfc7159#section-9
331+
const maxDepth = 10000
332+
333+
func (iter *Iterator) incrementDepth() (success bool) {
334+
iter.depth++
335+
if iter.depth <= maxDepth {
336+
return true
337+
}
338+
iter.ReportError("incrementDepth", "exceeded max depth")
339+
return false
340+
}
341+
342+
func (iter *Iterator) decrementDepth() (success bool) {
343+
iter.depth--
344+
if iter.depth >= 0 {
345+
return true
346+
}
347+
iter.ReportError("decrementDepth", "unexpected negative nesting")
348+
return false
349+
}

‎iter_array.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,32 @@ func (iter *Iterator) ReadArray() (ret bool) {
2828
func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) {
2929
c := iter.nextToken()
3030
if c == '[' {
31+
if !iter.incrementDepth() {
32+
return false
33+
}
3134
c = iter.nextToken()
3235
if c != ']' {
3336
iter.unreadByte()
3437
if !callback(iter) {
38+
iter.decrementDepth()
3539
return false
3640
}
3741
c = iter.nextToken()
3842
for c == ',' {
3943
if !callback(iter) {
44+
iter.decrementDepth()
4045
return false
4146
}
4247
c = iter.nextToken()
4348
}
4449
if c != ']' {
4550
iter.ReportError("ReadArrayCB", "expect ] in the end, but found "+string([]byte{c}))
51+
iter.decrementDepth()
4652
return false
4753
}
48-
return true
54+
return iter.decrementDepth()
4955
}
50-
return true
56+
return iter.decrementDepth()
5157
}
5258
if c == 'n' {
5359
iter.skipThreeBytes('u', 'l', 'l')

‎iter_object.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool {
112112
c := iter.nextToken()
113113
var field string
114114
if c == '{' {
115+
if !iter.incrementDepth() {
116+
return false
117+
}
115118
c = iter.nextToken()
116119
if c == '"' {
117120
iter.unreadByte()
@@ -121,6 +124,7 @@ func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool {
121124
iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
122125
}
123126
if !callback(iter, field) {
127+
iter.decrementDepth()
124128
return false
125129
}
126130
c = iter.nextToken()
@@ -131,20 +135,23 @@ func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool {
131135
iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
132136
}
133137
if !callback(iter, field) {
138+
iter.decrementDepth()
134139
return false
135140
}
136141
c = iter.nextToken()
137142
}
138143
if c != '}' {
139144
iter.ReportError("ReadObjectCB", `object not ended with }`)
145+
iter.decrementDepth()
140146
return false
141147
}
142-
return true
148+
return iter.decrementDepth()
143149
}
144150
if c == '}' {
145-
return true
151+
return iter.decrementDepth()
146152
}
147153
iter.ReportError("ReadObjectCB", `expect " after }, but found `+string([]byte{c}))
154+
iter.decrementDepth()
148155
return false
149156
}
150157
if c == 'n' {
@@ -159,39 +166,48 @@ func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool {
159166
func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool {
160167
c := iter.nextToken()
161168
if c == '{' {
169+
if !iter.incrementDepth() {
170+
return false
171+
}
162172
c = iter.nextToken()
163173
if c == '"' {
164174
iter.unreadByte()
165175
field := iter.ReadString()
166176
if iter.nextToken() != ':' {
167177
iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
178+
iter.decrementDepth()
168179
return false
169180
}
170181
if !callback(iter, field) {
182+
iter.decrementDepth()
171183
return false
172184
}
173185
c = iter.nextToken()
174186
for c == ',' {
175187
field = iter.ReadString()
176188
if iter.nextToken() != ':' {
177189
iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
190+
iter.decrementDepth()
178191
return false
179192
}
180193
if !callback(iter, field) {
194+
iter.decrementDepth()
181195
return false
182196
}
183197
c = iter.nextToken()
184198
}
185199
if c != '}' {
186200
iter.ReportError("ReadMapCB", `object not ended with }`)
201+
iter.decrementDepth()
187202
return false
188203
}
189-
return true
204+
return iter.decrementDepth()
190205
}
191206
if c == '}' {
192-
return true
207+
return iter.decrementDepth()
193208
}
194209
iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c}))
210+
iter.decrementDepth()
195211
return false
196212
}
197213
if c == 'n' {

‎iter_skip_sloppy.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ func (iter *Iterator) skipNumber() {
2222

2323
func (iter *Iterator) skipArray() {
2424
level := 1
25+
if !iter.incrementDepth() {
26+
return
27+
}
2528
for {
2629
for i := iter.head; i < iter.tail; i++ {
2730
switch iter.buf[i] {
@@ -31,8 +34,14 @@ func (iter *Iterator) skipArray() {
3134
i = iter.head - 1 // it will be i++ soon
3235
case '[': // If open symbol, increase level
3336
level++
37+
if !iter.incrementDepth() {
38+
return
39+
}
3440
case ']': // If close symbol, increase level
3541
level--
42+
if !iter.decrementDepth() {
43+
return
44+
}
3645

3746
// If we have returned to the original level, we're done
3847
if level == 0 {
@@ -50,6 +59,10 @@ func (iter *Iterator) skipArray() {
5059

5160
func (iter *Iterator) skipObject() {
5261
level := 1
62+
if !iter.incrementDepth() {
63+
return
64+
}
65+
5366
for {
5467
for i := iter.head; i < iter.tail; i++ {
5568
switch iter.buf[i] {
@@ -59,8 +72,14 @@ func (iter *Iterator) skipObject() {
5972
i = iter.head - 1 // it will be i++ soon
6073
case '{': // If open symbol, increase level
6174
level++
75+
if !iter.incrementDepth() {
76+
return
77+
}
6278
case '}': // If close symbol, increase level
6379
level--
80+
if !iter.decrementDepth() {
81+
return
82+
}
6483

6584
// If we have returned to the original level, we're done
6685
if level == 0 {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /