@@ -207,12 +207,12 @@ var (
207
207
)
208
208
209
209
// validateStructTag parses the struct tag and returns an error if it is not
210
- // in the canonical format, as defined by reflect.StructTag.
210
+ // in the canonical format, which is a space-separated list of key:"value"
211
+ // settings. The value may contain spaces.
211
212
func validateStructTag (tag string ) error {
212
213
// This code is based on the StructTag.Get code in package reflect.
213
214
214
215
n := 0
215
- var keys []string
216
216
for ; tag != "" ; n ++ {
217
217
if n > 0 && tag != "" && tag [0 ] != ' ' {
218
218
// More restrictive than reflect, but catches likely mistakes
@@ -240,27 +240,14 @@ func validateStructTag(tag string) error {
240
240
if i == 0 {
241
241
return errTagKeySyntax
242
242
}
243
- if i + 1 >= len (tag ) || tag [i ] < ' ' || tag [ i ] == 0x7f {
243
+ if i + 1 >= len (tag ) || tag [i ] != ':' {
244
244
return errTagSyntax
245
245
}
246
- key := tag [:i ]
247
- keys = append (keys , key )
248
- tag = tag [i :]
249
-
250
- // If we found a space char here - assume that we have a tag with
251
- // multiple keys.
252
- if tag [0 ] == ' ' {
253
- continue
254
- }
255
-
256
- // Spaces were filtered above so we assume that here we have
257
- // only valid tag value started with `:"`.
258
- if tag [0 ] != ':' || tag [1 ] != '"' {
246
+ if tag [i + 1 ] != '"' {
259
247
return errTagValueSyntax
260
248
}
261
-
262
- // Remove the colon leaving tag at the start of the quoted string.
263
- tag = tag [1 :]
249
+ key := tag [:i ]
250
+ tag = tag [i + 1 :]
264
251
265
252
// Scan quoted string to find value.
266
253
i = 1
@@ -276,56 +263,51 @@ func validateStructTag(tag string) error {
276
263
qvalue := tag [:i + 1 ]
277
264
tag = tag [i + 1 :]
278
265
279
- wholeValue , err := strconv .Unquote (qvalue )
266
+ value , err := strconv .Unquote (qvalue )
280
267
if err != nil {
281
268
return errTagValueSyntax
282
269
}
283
270
284
- for _ , key := range keys {
285
- if ! checkTagSpaces [key ] {
286
- continue
287
- }
288
-
289
- value := wholeValue
290
- switch key {
291
- case "xml" :
292
- // If the first or last character in the XML tag is a space, it is
293
- // suspicious.
294
- if strings .Trim (value , " " ) != value {
295
- return errTagValueSpace
296
- }
271
+ if ! checkTagSpaces [key ] {
272
+ continue
273
+ }
297
274
298
- // If there are multiple spaces, they are suspicious.
299
- if strings .Count (value , " " ) > 1 {
300
- return errTagValueSpace
301
- }
275
+ switch key {
276
+ case "xml" :
277
+ // If the first or last character in the XML tag is a space, it is
278
+ // suspicious.
279
+ if strings .Trim (value , " " ) != value {
280
+ return errTagValueSpace
281
+ }
302
282
303
- // If there is no comma, skip the rest of the checks.
304
- comma := strings .IndexRune (value , ',' )
305
- if comma < 0 {
306
- continue
307
- }
283
+ // If there are multiple spaces, they are suspicious.
284
+ if strings .Count (value , " " ) > 1 {
285
+ return errTagValueSpace
286
+ }
308
287
309
- // If the character before a comma is a space, this is suspicious.
310
- if comma > 0 && value [comma - 1 ] == ' ' {
311
- return errTagValueSpace
312
- }
313
- value = value [comma + 1 :]
314
- case "json" :
315
- // JSON allows using spaces in the name, so skip it.
316
- comma := strings .IndexRune (value , ',' )
317
- if comma < 0 {
318
- continue
319
- }
320
- value = value [comma + 1 :]
288
+ // If there is no comma, skip the rest of the checks.
289
+ comma := strings .IndexRune (value , ',' )
290
+ if comma < 0 {
291
+ continue
321
292
}
322
293
323
- if strings .IndexByte (value , ' ' ) >= 0 {
294
+ // If the character before a comma is a space, this is suspicious.
295
+ if comma > 0 && value [comma - 1 ] == ' ' {
324
296
return errTagValueSpace
325
297
}
298
+ value = value [comma + 1 :]
299
+ case "json" :
300
+ // JSON allows using spaces in the name, so skip it.
301
+ comma := strings .IndexRune (value , ',' )
302
+ if comma < 0 {
303
+ continue
304
+ }
305
+ value = value [comma + 1 :]
326
306
}
327
307
328
- keys = keys [:0 ]
308
+ if strings .IndexByte (value , ' ' ) >= 0 {
309
+ return errTagValueSpace
310
+ }
329
311
}
330
312
return nil
331
313
}
0 commit comments