@@ -103,9 +103,11 @@ export function deepSet(x: any, path: string[], value: any) {
103103
104104 while ( path . length > 1 && isObject ( x ) ) {
105105 const key = path . shift ( ) ! ;
106- if ( key === '__proto__' || key === 'constructor' || key === 'prototype' ) {
107- throw new ToolkitError ( `Invalid key: ${ key } ` ) ;
106+
107+ if ( isPrototypePollutingKey ( key ) ) {
108+ continue ;
108109 }
110+
109111 if ( ! ( key in x ) ) {
110112 x [ key ] = { } ;
111113 }
@@ -117,8 +119,9 @@ export function deepSet(x: any, path: string[], value: any) {
117119 }
118120
119121 const finalKey = path [ 0 ] ;
120- if ( finalKey === '__proto__' || finalKey === 'constructor' || finalKey === 'prototype' ) {
121- throw new ToolkitError ( `Invalid key: ${ finalKey } ` ) ;
122+
123+ if ( isPrototypePollutingKey ( finalKey ) ) {
124+ return ;
122125 }
123126
124127 if ( value !== undefined ) {
@@ -128,6 +131,16 @@ export function deepSet(x: any, path: string[], value: any) {
128131 }
129132}
130133
134+ /**
135+ * Helper to detect prototype polluting keys
136+ *
137+ * A key matching this, MUST NOT be used in an assignment.
138+ * Use this to check user-input.
139+ */
140+ function isPrototypePollutingKey ( key : string ) {
141+ return key === '__proto__' || key === 'constructor' || key === 'prototype' ;
142+ }
143+
131144/**
132145 * Recursively merge objects together
133146 *
@@ -139,7 +152,7 @@ export function deepSet(x: any, path: string[], value: any) {
139152export function deepMerge ( ...objects : Array < Obj < any > | undefined > ) {
140153 function mergeOne ( target : Obj < any > , source : Obj < any > ) {
141154 for ( const key of Object . keys ( source ) ) {
142- if ( key === '__proto__' || key === 'constructor' ) {
155+ if ( isPrototypePollutingKey ( key ) ) {
143156 continue ;
144157 }
145158
0 commit comments