@@ -30,6 +30,8 @@ var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i;
30
30
var PATTERN_TAG_URI = / ^ (?: ! | [ ^ , \[ \] \{ \} ] ) (?: % [ 0 - 9 a - f ] { 2 } | [ 0 - 9 a - z \- # ; \/ \? : @ & = \+ \$ , _ \. ! ~ \* ' \( \) \[ \] ] ) * $ / i;
31
31
32
32
33
+ function _class ( obj ) { return Object . prototype . toString . call ( obj ) ; }
34
+
33
35
function is_EOL ( c ) {
34
36
return ( c === 0x0A /* LF */ ) || ( c === 0x0D /* CR */ ) ;
35
37
}
@@ -287,16 +289,29 @@ function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valu
287
289
288
290
// The output is a plain object here, so keys can only be strings.
289
291
// We need to convert keyNode to a string, but doing so can hang the process
290
- // (deeply nested arrays that explode exponentially using aliases) or execute
291
- // code via toString.
292
+ // (deeply nested arrays that explode exponentially using aliases).
292
293
if ( Array . isArray ( keyNode ) ) {
294
+ keyNode = Array . prototype . slice . call ( keyNode ) ;
295
+
293
296
for ( index = 0 , quantity = keyNode . length ; index < quantity ; index += 1 ) {
294
297
if ( Array . isArray ( keyNode [ index ] ) ) {
295
298
throwError ( state , 'nested arrays are not supported inside keys' ) ;
296
299
}
300
+
301
+ if ( typeof keyNode === 'object' && _class ( keyNode [ index ] ) === '[object Object]' ) {
302
+ keyNode [ index ] = '[object Object]' ;
303
+ }
297
304
}
298
305
}
299
306
307
+ // Avoid code execution in load() via toString property
308
+ // (still use its own toString for arrays, timestamps,
309
+ // and whatever user schema extensions happen to have @@toStringTag )
310
+ if ( typeof keyNode === 'object' && _class ( keyNode ) === '[object Object]' ) {
311
+ keyNode = '[object Object]' ;
312
+ }
313
+
314
+
300
315
keyNode = String ( keyNode ) ;
301
316
302
317
if ( _result === null ) {
0 commit comments