diff --git a/Sources/Fuzzilli/Base/ProgramBuilder.swift b/Sources/Fuzzilli/Base/ProgramBuilder.swift index 3eb4cb968..9b8b380e7 100644 --- a/Sources/Fuzzilli/Base/ProgramBuilder.swift +++ b/Sources/Fuzzilli/Base/ProgramBuilder.swift @@ -2039,6 +2039,11 @@ public class ProgramBuilder { return emit(TypeOf(), withInputs: [v]).output } + @discardableResult + public func void(_ v: Variable) -> Variable { + return emit(Void_(), withInputs: [v]).output + } + @discardableResult public func testInstanceOf(_ v: Variable, _ type: Variable) -> Variable { return emit(TestInstanceOf(), withInputs: [v, type]).output diff --git a/Sources/Fuzzilli/CodeGen/CodeGeneratorWeights.swift b/Sources/Fuzzilli/CodeGen/CodeGeneratorWeights.swift index 9ce5be34a..fdc7ad219 100644 --- a/Sources/Fuzzilli/CodeGen/CodeGeneratorWeights.swift +++ b/Sources/Fuzzilli/CodeGen/CodeGeneratorWeights.swift @@ -192,4 +192,5 @@ public let codeGeneratorWeights = [ "ApiConstructorCallGenerator": 15, "ApiMethodCallGenerator": 15, "ApiFunctionCallGenerator": 15, + "VoidGenerator": 1, ] diff --git a/Sources/Fuzzilli/CodeGen/CodeGenerators.swift b/Sources/Fuzzilli/CodeGen/CodeGenerators.swift index f8a9cd5f7..d8e1aa3a8 100644 --- a/Sources/Fuzzilli/CodeGen/CodeGenerators.swift +++ b/Sources/Fuzzilli/CodeGen/CodeGenerators.swift @@ -970,6 +970,10 @@ public let CodeGenerators: [CodeGenerator] = [ b.compare(type, with: rhs, using: .strictEqual) }, + CodeGenerator("VoidGenerator", inputs: .one) { b, val in + b.void(val) + }, + CodeGenerator("InstanceOfGenerator", inputs: .preferred(.anything, .constructor())) { b, val, cls in b.testInstanceOf(val, cls) }, diff --git a/Sources/Fuzzilli/FuzzIL/Instruction.swift b/Sources/Fuzzilli/FuzzIL/Instruction.swift index d770196b2..4ba5c2792 100644 --- a/Sources/Fuzzilli/FuzzIL/Instruction.swift +++ b/Sources/Fuzzilli/FuzzIL/Instruction.swift @@ -565,6 +565,8 @@ extension Instruction: ProtobufConvertible { } case .typeOf: $0.typeOf = Fuzzilli_Protobuf_TypeOf() + case .void: + $0.void = Fuzzilli_Protobuf_Void() case .testInstanceOf: $0.testInstanceOf = Fuzzilli_Protobuf_TestInstanceOf() case .testIn: @@ -1042,6 +1044,8 @@ extension Instruction: ProtobufConvertible { op = ConfigureComputedProperty(flags: flags, type: try convertEnum(p.type, PropertyType.allCases)) case .typeOf: op = TypeOf() + case .void: + op = Void_() case .testInstanceOf: op = TestInstanceOf() case .testIn: diff --git a/Sources/Fuzzilli/FuzzIL/JSTyper.swift b/Sources/Fuzzilli/FuzzIL/JSTyper.swift index dc9858454..662c2bb88 100644 --- a/Sources/Fuzzilli/FuzzIL/JSTyper.swift +++ b/Sources/Fuzzilli/FuzzIL/JSTyper.swift @@ -675,6 +675,9 @@ public struct JSTyper: Analyzer { case .typeOf: set(instr.output, .string) + case .void: + set(instr.output, .undefined) + case .testInstanceOf: set(instr.output, .boolean) diff --git a/Sources/Fuzzilli/FuzzIL/JsOperations.swift b/Sources/Fuzzilli/FuzzIL/JsOperations.swift index bab2bd749..14597a2a8 100644 --- a/Sources/Fuzzilli/FuzzIL/JsOperations.swift +++ b/Sources/Fuzzilli/FuzzIL/JsOperations.swift @@ -1030,6 +1030,14 @@ final class TypeOf: JsOperation { } } +final class Void_: JsOperation { + override var opcode: Opcode { .void(self) } + + init() { + super.init(numInputs: 1, numOutputs: 1) + } +} + final class TestInstanceOf: JsOperation { override var opcode: Opcode { .testInstanceOf(self) } diff --git a/Sources/Fuzzilli/FuzzIL/Opcodes.swift b/Sources/Fuzzilli/FuzzIL/Opcodes.swift index e0b9f37fa..8f376ea09 100644 --- a/Sources/Fuzzilli/FuzzIL/Opcodes.swift +++ b/Sources/Fuzzilli/FuzzIL/Opcodes.swift @@ -106,6 +106,7 @@ enum Opcode { case deleteComputedProperty(DeleteComputedProperty) case configureComputedProperty(ConfigureComputedProperty) case typeOf(TypeOf) + case void(Void_) case testInstanceOf(TestInstanceOf) case testIn(TestIn) case beginPlainFunction(BeginPlainFunction) diff --git a/Sources/Fuzzilli/Lifting/FuzzILLifter.swift b/Sources/Fuzzilli/Lifting/FuzzILLifter.swift index aa489854b..8bfe3507c 100644 --- a/Sources/Fuzzilli/Lifting/FuzzILLifter.swift +++ b/Sources/Fuzzilli/Lifting/FuzzILLifter.swift @@ -366,6 +366,9 @@ public class FuzzILLifter: Lifter { case .typeOf: w.emit("\(output()) <- TypeOf \(input(0))") + case .void: + w.emit("\(output()) <- Void_ \(input(0))") + case .testInstanceOf: w.emit("\(output()) <- TestInstanceOf \(input(0)), \(input(1))") diff --git a/Sources/Fuzzilli/Lifting/JavaScriptLifter.swift b/Sources/Fuzzilli/Lifting/JavaScriptLifter.swift index 240f3ea99..b7de0815e 100644 --- a/Sources/Fuzzilli/Lifting/JavaScriptLifter.swift +++ b/Sources/Fuzzilli/Lifting/JavaScriptLifter.swift @@ -642,6 +642,10 @@ public class JavaScriptLifter: Lifter { let expr = UnaryExpression.new() + "typeof " + input(0) w.assign(expr, to: instr.output) + case .void: + let expr = UnaryExpression.new() + "void " + input(0) + w.assign(expr, to: instr.output) + case .testInstanceOf: let lhs = input(0) let rhs = input(1) diff --git a/Sources/Fuzzilli/Protobuf/operations.pb.swift b/Sources/Fuzzilli/Protobuf/operations.pb.swift index 5bb356cdc..1d2f2dd6e 100644 --- a/Sources/Fuzzilli/Protobuf/operations.pb.swift +++ b/Sources/Fuzzilli/Protobuf/operations.pb.swift @@ -1278,6 +1278,16 @@ public struct Fuzzilli_Protobuf_TypeOf: Sendable { public init() {} } +public struct Fuzzilli_Protobuf_Void: Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + public init() {} +} + public struct Fuzzilli_Protobuf_TestInstanceOf: Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for @@ -4885,6 +4895,25 @@ extension Fuzzilli_Protobuf_TypeOf: SwiftProtobuf.Message, SwiftProtobuf._Messag } } +extension Fuzzilli_Protobuf_Void: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".Void" + public static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + public mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + public func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: Fuzzilli_Protobuf_Void, rhs: Fuzzilli_Protobuf_Void) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + extension Fuzzilli_Protobuf_TestInstanceOf: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".TestInstanceOf" public static let _protobuf_nameMap = SwiftProtobuf._NameMap() diff --git a/Sources/Fuzzilli/Protobuf/operations.proto b/Sources/Fuzzilli/Protobuf/operations.proto index 524e45a83..292ae8ce4 100644 --- a/Sources/Fuzzilli/Protobuf/operations.proto +++ b/Sources/Fuzzilli/Protobuf/operations.proto @@ -337,6 +337,9 @@ message ConfigureComputedProperty { message TypeOf { } +message Void { +} + message TestInstanceOf { } diff --git a/Sources/Fuzzilli/Protobuf/program.pb.swift b/Sources/Fuzzilli/Protobuf/program.pb.swift index b04230473..9eec4ff46 100644 --- a/Sources/Fuzzilli/Protobuf/program.pb.swift +++ b/Sources/Fuzzilli/Protobuf/program.pb.swift @@ -680,6 +680,14 @@ public struct Fuzzilli_Protobuf_Instruction: Sendable { set {operation = .typeOf(newValue)} } + public var void: Fuzzilli_Protobuf_Void { + get { + if case .void(let v)? = operation {return v} + return Fuzzilli_Protobuf_Void() + } + set {operation = .void(newValue)} + } + public var testInstanceOf: Fuzzilli_Protobuf_TestInstanceOf { get { if case .testInstanceOf(let v)? = operation {return v} @@ -1554,6 +1562,7 @@ public struct Fuzzilli_Protobuf_Instruction: Sendable { case deleteComputedProperty(Fuzzilli_Protobuf_DeleteComputedProperty) case configureComputedProperty(Fuzzilli_Protobuf_ConfigureComputedProperty) case typeOf(Fuzzilli_Protobuf_TypeOf) + case void(Fuzzilli_Protobuf_Void) case testInstanceOf(Fuzzilli_Protobuf_TestInstanceOf) case testIn(Fuzzilli_Protobuf_TestIn) case beginPlainFunction(Fuzzilli_Protobuf_BeginPlainFunction) @@ -1881,6 +1890,7 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M 177: .same(proto: "explore"), 178: .same(proto: "probe"), 179: .same(proto: "fixup"), + 180: .same(proto: "void"), ] public mutating func decodeMessage(decoder: inout D) throws { @@ -4199,6 +4209,19 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M self.operation = .fixup(v) } }() + case 180: try { + var v: Fuzzilli_Protobuf_Void? + var hadOneofValue = false + if let current = self.operation { + hadOneofValue = true + if case .void(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.operation = .void(v) + } + }() default: break } } @@ -4529,6 +4552,10 @@ extension Fuzzilli_Protobuf_Instruction: SwiftProtobuf.Message, SwiftProtobuf._M guard case .typeOf(let v)? = self.operation else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 80) }() + case .void?: try { + guard case .void(let v)? = self.operation else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 80) + }() case .testInstanceOf?: try { guard case .testInstanceOf(let v)? = self.operation else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 81) diff --git a/Sources/Fuzzilli/Protobuf/program.proto b/Sources/Fuzzilli/Protobuf/program.proto index c8da3a390..787f81b79 100644 --- a/Sources/Fuzzilli/Protobuf/program.proto +++ b/Sources/Fuzzilli/Protobuf/program.proto @@ -203,6 +203,7 @@ message Instruction { Explore explore = 177; Probe probe = 178; Fixup fixup = 179; + Void void = 180; } }