Skip to content

Commit c12f86f

Browse files
authored
fix: validate key before proceeding with deep assignment (#8869)
1 parent 3fe27d7 commit c12f86f

File tree

4 files changed

+47
-12
lines changed

4 files changed

+47
-12
lines changed

.changeset/fresh-rats-hide.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"builder-util": patch
3+
---
4+
5+
fix: validate object key before deep assigning

packages/builder-util/src/DebugLogger.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { outputFile } from "fs-extra"
22
import { serializeToYaml } from "./util"
3+
import { mapToObject } from "./mapper"
34

45
export class DebugLogger {
5-
readonly data: any = {}
6+
readonly data = new Map<string, any>()
67

78
constructor(readonly isEnabled = true) {}
89

@@ -19,26 +20,27 @@ export class DebugLogger {
1920
lastName = p
2021
break
2122
} else {
22-
if (o[p] == null) {
23-
o[p] = Object.create(null)
24-
} else if (typeof o[p] === "string") {
25-
o[p] = [o[p]]
23+
if (!o.has(p)) {
24+
o.set(p, new Map<string, any>())
25+
} else if (typeof o.get(p) === "string") {
26+
o.set(p, [o.get(p)])
2627
}
27-
o = o[p]
28+
o = o.get(p)
2829
}
2930
}
3031

31-
if (Array.isArray(o[lastName!])) {
32-
o[lastName!] = [...o[lastName!], value]
32+
if (Array.isArray(o.get(lastName!))) {
33+
o.set(lastName!, [...o.get(lastName!), value])
3334
} else {
34-
o[lastName!] = value
35+
o.set(lastName!, value)
3536
}
3637
}
3738

3839
save(file: string) {
40+
const data = mapToObject(this.data)
3941
// toml and json doesn't correctly output multiline string as multiline
40-
if (this.isEnabled && Object.keys(this.data).length > 0) {
41-
return outputFile(file, serializeToYaml(this.data))
42+
if (this.isEnabled && Object.keys(data).length > 0) {
43+
return outputFile(file, serializeToYaml(data))
4244
} else {
4345
return Promise.resolve()
4446
}

packages/builder-util/src/deepAssign.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { isValidKey } from "./mapper"
2+
13
function isObject(x: any) {
24
if (Array.isArray(x)) {
35
return false
@@ -30,7 +32,9 @@ function assignKey(target: any, from: any, key: string) {
3032
function assign(to: any, from: any) {
3133
if (to !== from) {
3234
for (const key of Object.getOwnPropertyNames(from)) {
33-
assignKey(to, from, key)
35+
if (isValidKey(key)) {
36+
assignKey(to, from, key)
37+
}
3438
}
3539
}
3640
return to

packages/builder-util/src/mapper.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
type RecursiveMap = Map<any, RecursiveMap | any>
2+
3+
export function mapToObject(map: RecursiveMap) {
4+
const obj: any = {}
5+
for (const [key, value] of map) {
6+
if (!isValidKey(key)) {
7+
continue
8+
}
9+
if (value instanceof Map) {
10+
obj[key] = mapToObject(value)
11+
} else {
12+
obj[key] = value
13+
}
14+
}
15+
return obj
16+
}
17+
18+
export function isValidKey(key: any) {
19+
const protectedProperties = ["__proto__", "prototype", "constructor"]
20+
if (protectedProperties.includes(key)) {
21+
return false
22+
}
23+
return ["string", "number", "symbol", "boolean"].includes(typeof key) || key === null
24+
}

0 commit comments

Comments
 (0)