@@ -30,6 +30,8 @@ var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i;
3030var PATTERN_TAG_URI = / ^ (?: ! | [ ^ , \[ \] \{ \} ] ) (?: % [ 0 - 9 a - f ] { 2 } | [ 0 - 9 a - z \- # ; \/ \? : @ & = \+ \$ , _ \. ! ~ \* ' \( \) \[ \] ] ) * $ / i;
3131
3232
33+ function _class ( obj ) { return Object . prototype . toString . call ( obj ) ; }
34+
3335function is_EOL ( c ) {
3436 return ( c === 0x0A /* LF */ ) || ( c === 0x0D /* CR */ ) ;
3537}
@@ -287,16 +289,29 @@ function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valu
287289
288290 // The output is a plain object here, so keys can only be strings.
289291 // 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).
292293 if ( Array . isArray ( keyNode ) ) {
294+ keyNode = Array . prototype . slice . call ( keyNode ) ;
295+
293296 for ( index = 0 , quantity = keyNode . length ; index < quantity ; index += 1 ) {
294297 if ( Array . isArray ( keyNode [ index ] ) ) {
295298 throwError ( state , 'nested arrays are not supported inside keys' ) ;
296299 }
300+
301+ if ( typeof keyNode === 'object' && _class ( keyNode [ index ] ) === '[object Object]' ) {
302+ keyNode [ index ] = '[object Object]' ;
303+ }
297304 }
298305 }
299306
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+
300315 keyNode = String ( keyNode ) ;
301316
302317 if ( _result === null ) {
0 commit comments