@@ -9,12 +9,12 @@ import (
9
9
"time"
10
10
)
11
11
12
- var unfuns [_maxtype ]func (jsWriter , []byte , []byte ) ([]byte , []byte , error )
12
+ var unfuns [_maxtype ]func (jsWriter , []byte , []byte , int ) ([]byte , []byte , error )
13
13
14
14
func init () {
15
15
// NOTE(pmh): this is best expressed as a jump table,
16
16
// but gc doesn't do that yet. revisit post-go1.5.
17
- unfuns = [_maxtype ]func (jsWriter , []byte , []byte ) ([]byte , []byte , error ){
17
+ unfuns = [_maxtype ]func (jsWriter , []byte , []byte , int ) ([]byte , []byte , error ){
18
18
StrType : rwStringBytes ,
19
19
BinType : rwBytesBytes ,
20
20
MapType : rwMapBytes ,
@@ -51,15 +51,15 @@ func UnmarshalAsJSON(w io.Writer, msg []byte) ([]byte, error) {
51
51
dst = bufio .NewWriterSize (w , 512 )
52
52
}
53
53
for len (msg ) > 0 && err == nil {
54
- msg , scratch , err = writeNext (dst , msg , scratch )
54
+ msg , scratch , err = writeNext (dst , msg , scratch , 0 )
55
55
}
56
56
if ! cast && err == nil {
57
57
err = dst .(* bufio.Writer ).Flush ()
58
58
}
59
59
return msg , err
60
60
}
61
61
62
- func writeNext (w jsWriter , msg []byte , scratch []byte ) ([]byte , []byte , error ) {
62
+ func writeNext (w jsWriter , msg []byte , scratch []byte , depth int ) ([]byte , []byte , error ) {
63
63
if len (msg ) < 1 {
64
64
return msg , scratch , ErrShortBytes
65
65
}
@@ -76,10 +76,13 @@ func writeNext(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
76
76
t = TimeType
77
77
}
78
78
}
79
- return unfuns [t ](w , msg , scratch )
79
+ return unfuns [t ](w , msg , scratch , depth )
80
80
}
81
81
82
- func rwArrayBytes (w jsWriter , msg []byte , scratch []byte ) ([]byte , []byte , error ) {
82
+ func rwArrayBytes (w jsWriter , msg []byte , scratch []byte , depth int ) ([]byte , []byte , error ) {
83
+ if depth >= recursionLimit {
84
+ return msg , scratch , ErrRecursion
85
+ }
83
86
sz , msg , err := ReadArrayHeaderBytes (msg )
84
87
if err != nil {
85
88
return msg , scratch , err
@@ -95,7 +98,7 @@ func rwArrayBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error
95
98
return msg , scratch , err
96
99
}
97
100
}
98
- msg , scratch , err = writeNext (w , msg , scratch )
101
+ msg , scratch , err = writeNext (w , msg , scratch , depth + 1 )
99
102
if err != nil {
100
103
return msg , scratch , err
101
104
}
@@ -104,7 +107,10 @@ func rwArrayBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error
104
107
return msg , scratch , err
105
108
}
106
109
107
- func rwMapBytes (w jsWriter , msg []byte , scratch []byte ) ([]byte , []byte , error ) {
110
+ func rwMapBytes (w jsWriter , msg []byte , scratch []byte , depth int ) ([]byte , []byte , error ) {
111
+ if depth >= recursionLimit {
112
+ return msg , scratch , ErrRecursion
113
+ }
108
114
sz , msg , err := ReadMapHeaderBytes (msg )
109
115
if err != nil {
110
116
return msg , scratch , err
@@ -120,15 +126,15 @@ func rwMapBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error)
120
126
return msg , scratch , err
121
127
}
122
128
}
123
- msg , scratch , err = rwMapKeyBytes (w , msg , scratch )
129
+ msg , scratch , err = rwMapKeyBytes (w , msg , scratch , depth )
124
130
if err != nil {
125
131
return msg , scratch , err
126
132
}
127
133
err = w .WriteByte (':' )
128
134
if err != nil {
129
135
return msg , scratch , err
130
136
}
131
- msg , scratch , err = writeNext (w , msg , scratch )
137
+ msg , scratch , err = writeNext (w , msg , scratch , depth + 1 )
132
138
if err != nil {
133
139
return msg , scratch , err
134
140
}
@@ -137,17 +143,17 @@ func rwMapBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error)
137
143
return msg , scratch , err
138
144
}
139
145
140
- func rwMapKeyBytes (w jsWriter , msg []byte , scratch []byte ) ([]byte , []byte , error ) {
141
- msg , scratch , err := rwStringBytes (w , msg , scratch )
146
+ func rwMapKeyBytes (w jsWriter , msg []byte , scratch []byte , depth int ) ([]byte , []byte , error ) {
147
+ msg , scratch , err := rwStringBytes (w , msg , scratch , depth )
142
148
if err != nil {
143
149
if tperr , ok := err .(TypeError ); ok && tperr .Encoded == BinType {
144
- return rwBytesBytes (w , msg , scratch )
150
+ return rwBytesBytes (w , msg , scratch , depth )
145
151
}
146
152
}
147
153
return msg , scratch , err
148
154
}
149
155
150
- func rwStringBytes (w jsWriter , msg []byte , scratch []byte ) ([]byte , []byte , error ) {
156
+ func rwStringBytes (w jsWriter , msg []byte , scratch []byte , depth int ) ([]byte , []byte , error ) {
151
157
str , msg , err := ReadStringZC (msg )
152
158
if err != nil {
153
159
return msg , scratch , err
@@ -156,7 +162,7 @@ func rwStringBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, erro
156
162
return msg , scratch , err
157
163
}
158
164
159
- func rwBytesBytes (w jsWriter , msg []byte , scratch []byte ) ([]byte , []byte , error ) {
165
+ func rwBytesBytes (w jsWriter , msg []byte , scratch []byte , depth int ) ([]byte , []byte , error ) {
160
166
bts , msg , err := ReadBytesZC (msg )
161
167
if err != nil {
162
168
return msg , scratch , err
@@ -180,7 +186,7 @@ func rwBytesBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error
180
186
return msg , scratch , err
181
187
}
182
188
183
- func rwNullBytes (w jsWriter , msg []byte , scratch []byte ) ([]byte , []byte , error ) {
189
+ func rwNullBytes (w jsWriter , msg []byte , scratch []byte , depth int ) ([]byte , []byte , error ) {
184
190
msg , err := ReadNilBytes (msg )
185
191
if err != nil {
186
192
return msg , scratch , err
@@ -189,7 +195,7 @@ func rwNullBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error)
189
195
return msg , scratch , err
190
196
}
191
197
192
- func rwBoolBytes (w jsWriter , msg []byte , scratch []byte ) ([]byte , []byte , error ) {
198
+ func rwBoolBytes (w jsWriter , msg []byte , scratch []byte , depth int ) ([]byte , []byte , error ) {
193
199
b , msg , err := ReadBoolBytes (msg )
194
200
if err != nil {
195
201
return msg , scratch , err
@@ -202,7 +208,7 @@ func rwBoolBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error)
202
208
return msg , scratch , err
203
209
}
204
210
205
- func rwIntBytes (w jsWriter , msg []byte , scratch []byte ) ([]byte , []byte , error ) {
211
+ func rwIntBytes (w jsWriter , msg []byte , scratch []byte , depth int ) ([]byte , []byte , error ) {
206
212
i , msg , err := ReadInt64Bytes (msg )
207
213
if err != nil {
208
214
return msg , scratch , err
@@ -212,7 +218,7 @@ func rwIntBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error)
212
218
return msg , scratch , err
213
219
}
214
220
215
- func rwUintBytes (w jsWriter , msg []byte , scratch []byte ) ([]byte , []byte , error ) {
221
+ func rwUintBytes (w jsWriter , msg []byte , scratch []byte , depth int ) ([]byte , []byte , error ) {
216
222
u , msg , err := ReadUint64Bytes (msg )
217
223
if err != nil {
218
224
return msg , scratch , err
@@ -222,7 +228,7 @@ func rwUintBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error)
222
228
return msg , scratch , err
223
229
}
224
230
225
- func rwFloat32Bytes (w jsWriter , msg []byte , scratch []byte ) ([]byte , []byte , error ) {
231
+ func rwFloat32Bytes (w jsWriter , msg []byte , scratch []byte , depth int ) ([]byte , []byte , error ) {
226
232
var f float32
227
233
var err error
228
234
f , msg , err = ReadFloat32Bytes (msg )
@@ -234,7 +240,7 @@ func rwFloat32Bytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, err
234
240
return msg , scratch , err
235
241
}
236
242
237
- func rwFloat64Bytes (w jsWriter , msg []byte , scratch []byte ) ([]byte , []byte , error ) {
243
+ func rwFloat64Bytes (w jsWriter , msg []byte , scratch []byte , depth int ) ([]byte , []byte , error ) {
238
244
var f float64
239
245
var err error
240
246
f , msg , err = ReadFloat64Bytes (msg )
@@ -246,7 +252,7 @@ func rwFloat64Bytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, err
246
252
return msg , scratch , err
247
253
}
248
254
249
- func rwTimeBytes (w jsWriter , msg []byte , scratch []byte ) ([]byte , []byte , error ) {
255
+ func rwTimeBytes (w jsWriter , msg []byte , scratch []byte , depth int ) ([]byte , []byte , error ) {
250
256
var t time.Time
251
257
var err error
252
258
t , msg , err = ReadTimeBytes (msg )
@@ -261,7 +267,7 @@ func rwTimeBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error)
261
267
return msg , scratch , err
262
268
}
263
269
264
- func rwExtensionBytes (w jsWriter , msg []byte , scratch []byte ) ([]byte , []byte , error ) {
270
+ func rwExtensionBytes (w jsWriter , msg []byte , scratch []byte , depth int ) ([]byte , []byte , error ) {
265
271
var err error
266
272
var et int8
267
273
et , err = peekExtension (msg )
0 commit comments