Skip to content

Commit

Permalink
fix: validate key before proceeding with deep assignment (#8869)
Browse files Browse the repository at this point in the history
  • Loading branch information
mmaietta authored Feb 17, 2025
1 parent 3fe27d7 commit c12f86f
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changeset/fresh-rats-hide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"builder-util": patch
---

fix: validate object key before deep assigning
24 changes: 13 additions & 11 deletions packages/builder-util/src/DebugLogger.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { outputFile } from "fs-extra"
import { serializeToYaml } from "./util"
import { mapToObject } from "./mapper"

export class DebugLogger {
readonly data: any = {}
readonly data = new Map<string, any>()

constructor(readonly isEnabled = true) {}

Expand All @@ -19,26 +20,27 @@ export class DebugLogger {
lastName = p
break
} else {
if (o[p] == null) {
o[p] = Object.create(null)
} else if (typeof o[p] === "string") {
o[p] = [o[p]]
if (!o.has(p)) {
o.set(p, new Map<string, any>())
} else if (typeof o.get(p) === "string") {
o.set(p, [o.get(p)])
}
o = o[p]
o = o.get(p)
}
}

if (Array.isArray(o[lastName!])) {
o[lastName!] = [...o[lastName!], value]
if (Array.isArray(o.get(lastName!))) {
o.set(lastName!, [...o.get(lastName!), value])
} else {
o[lastName!] = value
o.set(lastName!, value)
}
}

save(file: string) {
const data = mapToObject(this.data)
// toml and json doesn't correctly output multiline string as multiline
if (this.isEnabled && Object.keys(this.data).length > 0) {
return outputFile(file, serializeToYaml(this.data))
if (this.isEnabled && Object.keys(data).length > 0) {
return outputFile(file, serializeToYaml(data))
} else {
return Promise.resolve()
}
Expand Down
6 changes: 5 additions & 1 deletion packages/builder-util/src/deepAssign.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { isValidKey } from "./mapper"

function isObject(x: any) {
if (Array.isArray(x)) {
return false
Expand Down Expand Up @@ -30,7 +32,9 @@ function assignKey(target: any, from: any, key: string) {
function assign(to: any, from: any) {
if (to !== from) {
for (const key of Object.getOwnPropertyNames(from)) {
assignKey(to, from, key)
if (isValidKey(key)) {
assignKey(to, from, key)
}
}
}
return to
Expand Down
24 changes: 24 additions & 0 deletions packages/builder-util/src/mapper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
type RecursiveMap = Map<any, RecursiveMap | any>

export function mapToObject(map: RecursiveMap) {
const obj: any = {}
for (const [key, value] of map) {
if (!isValidKey(key)) {
continue
}
if (value instanceof Map) {
obj[key] = mapToObject(value)
} else {
obj[key] = value
}
}
return obj
}

export function isValidKey(key: any) {
const protectedProperties = ["__proto__", "prototype", "constructor"]
if (protectedProperties.includes(key)) {
return false
}
return ["string", "number", "symbol", "boolean"].includes(typeof key) || key === null
}

0 comments on commit c12f86f

Please sign in to comment.