Skip to content

Commit aeaf575

Browse files
author
Samuel Groß
committed
Allow Symbols to be constructed by generateVariable
1 parent 5e21667 commit aeaf575

File tree

3 files changed

+26
-12
lines changed

3 files changed

+26
-12
lines changed

Sources/Fuzzilli/Core/Environment.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public protocol Environment: Component {
7373
/// Used e.g. for arrays created through a literal.
7474
var arrayType: Type { get }
7575

76-
/// Returns an array of constructable types
76+
/// All other types exposed by the environment for which a constructor builtin exists. E.g. Uint8Array or Symbol in Javascript.
7777
var constructables: [String] { get }
7878

7979
/// Retuns the type representing a function with the given signature.

Sources/Fuzzilli/Core/JavaScriptEnvironment.swift

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ public class JavaScriptEnvironment: ComponentBase, Environment {
6868
private var groups: [String: ObjectGroup] = [:]
6969

7070
public var constructables = [String]()
71-
public let nonConstructables = ["Math", "JSON", "Reflect", "Symbol"]
71+
72+
// Builtin objects (ObjectGroups to be precise) that are not constructors.
73+
public let nonConstructors = ["Math", "JSON", "Reflect"]
7274

7375
public init(additionalBuiltins: [String: Type], additionalObjectGroups: [ObjectGroup]) {
7476
super.init(name: "JavaScriptEnvironment")
@@ -183,13 +185,15 @@ public class JavaScriptEnvironment: ComponentBase, Environment {
183185
for group in groups.keys where !group.contains("Constructor") {
184186
assert(builtins.contains(group), "We cannot call the constructor for the given group \(group)")
185187

186-
if !nonConstructables.contains(group) {
187-
assert(type(ofBuiltin: group).constructorSignature != nil, "We don't have a constructor signature for \(group)")
188-
// These are basically the groups that need to be constructable i.e. callable with the new keyword.
188+
if !nonConstructors.contains(group) {
189+
// These are the groups that are constructable i.e. for which a builtin exists with the name of the group
190+
// that can be called as function or constructor and returns an object of that group.
191+
assert(type(ofBuiltin: group).signature != nil, "We don't have a constructor signature for \(group)")
192+
assert(type(ofBuiltin: group).signature!.outputType.group == group, "The constructor for \(group) returns an invalid type")
189193
constructables.append(group)
190194
}
191195
}
192-
196+
193197
customPropertyNames = ["a", "b", "c", "d", "e"]
194198
customMethodNames = ["m", "n", "o", "p"]
195199
methodNames.formUnion(customMethodNames)
@@ -346,7 +350,7 @@ public extension Type {
346350
}
347351

348352
/// Type of the JavaScript Object constructor builtin.
349-
static let jsObjectConstructor = .functionAndConstructor([.anything...] => .object()) + .object(ofGroup: "ObjectConstructor", withProperties: ["prototype"], withMethods: ["assign", "fromEntries", "getOwnPropertyDescriptor", "getOwnPropertyDescriptors", "getOwnPropertyNames", "getOwnPropertySymbols", "is", "preventExtensions", "seal", "create", "defineProperties", "defineProperty", "freeze", "getPrototypeOf", "setPrototypeOf", "isExtensible", "isFrozen", "isSealed", "keys", "entries", "values"])
353+
static let jsObjectConstructor = .functionAndConstructor([.anything...] => .object(ofGroup: "Object")) + .object(ofGroup: "ObjectConstructor", withProperties: ["prototype"], withMethods: ["assign", "fromEntries", "getOwnPropertyDescriptor", "getOwnPropertyDescriptors", "getOwnPropertyNames", "getOwnPropertySymbols", "is", "preventExtensions", "seal", "create", "defineProperties", "defineProperty", "freeze", "getPrototypeOf", "setPrototypeOf", "isExtensible", "isFrozen", "isSealed", "keys", "entries", "values"])
350354

351355
/// Type of the JavaScript Array constructor builtin.
352356
static let jsArrayConstructor = .functionAndConstructor([.integer] => .jsArray) + .object(ofGroup: "ArrayConstructor", withProperties: ["prototype"], withMethods: ["from", "of", "isArray"])

Sources/Fuzzilli/Core/ProgramBuilder.swift

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -477,12 +477,22 @@ public class ProgramBuilder {
477477
}
478478

479479
if let group = type.group {
480-
// We check this during Environment initialization, but let's keep this just in case.
481-
assert(fuzzer.environment.type(ofBuiltin: group) != .unknown, "We don't know how to construct \(group)")
482-
let constructionSignature = fuzzer.environment.type(ofBuiltin: group).constructorSignature!
483-
let arguments = generateCallArguments(for: constructionSignature)
480+
// Objects with predefined groups must be constructable through a Builtin exposed by the Environment.
481+
// Normally, that builtin is a .constructor(), but we also allow just a .function() for constructing object.
482+
// This is for example necessary for JavaScript Symbols, as the Symbol builtin is not a constructor.
483+
let constructorType = fuzzer.environment.type(ofBuiltin: group)
484+
assert(constructorType.Is(.function() | .constructor()), "We don't know how to construct \(group)")
485+
assert(constructorType.signature != nil, "We don't know how to construct \(group) (missing signature for constructor)")
486+
assert(constructorType.signature!.outputType.group == group, "We don't know how to construct \(group) (invalid signature for constructor)")
487+
488+
let constructorSignature = constructorType.signature!
489+
let arguments = generateCallArguments(for: constructorSignature)
484490
let constructor = loadBuiltin(group)
485-
obj = construct(constructor, withArgs: arguments)
491+
if !constructorType.Is(.constructor()) {
492+
obj = callFunction(constructor, withArgs: arguments)
493+
} else {
494+
obj = construct(constructor, withArgs: arguments)
495+
}
486496
} else {
487497
// Either generate a literal or use the store property stuff.
488498
if probability(0.8) { // Do the literal

0 commit comments

Comments
 (0)