Skip to content

Commit

Permalink
Add ComputedSuperProperty instructions
Browse files Browse the repository at this point in the history
Fuzzilli is now able to emit computed super property accesses.
E.g.:
  super[foo()] = 42;
or:
  let baz = super[bar()];
  • Loading branch information
carl-smith committed Nov 21, 2023
1 parent 4811845 commit 5696921
Show file tree
Hide file tree
Showing 14 changed files with 440 additions and 176 deletions.
9 changes: 9 additions & 0 deletions Sources/Fuzzilli/Base/ProgramBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2198,6 +2198,15 @@ public class ProgramBuilder {
emit(SetSuperProperty(propertyName: name), withInputs: [value])
}

@discardableResult
public func getComputedSuperProperty(_ property: Variable) -> Variable {
return emit(GetComputedSuperProperty(), withInputs: [property]).output
}

public func setComputedSuperProperty(_ property: Variable, to value: Variable) {
emit(SetComputedSuperProperty(), withInputs: [property, value])
}

public func updateSuperProperty(_ name: String, with value: Variable, using op: BinaryOperator) {
emit(UpdateSuperProperty(propertyName: name, operator: op), withInputs: [value])
}
Expand Down
2 changes: 2 additions & 0 deletions Sources/Fuzzilli/CodeGen/CodeGeneratorWeights.swift
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ public let codeGeneratorWeights = [
// These will only be used inside class- or object literal methods.
"SuperPropertyRetrievalGenerator": 20,
"SuperPropertyAssignmentGenerator": 20,
"ComputedSuperPropertyRetrievalGenerator": 20,
"ComputedSuperPropertyAssignmentGenerator": 20,
"SuperPropertyUpdateGenerator": 10,

"IfElseGenerator": 10,
Expand Down
12 changes: 12 additions & 0 deletions Sources/Fuzzilli/CodeGen/CodeGenerators.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1259,6 +1259,18 @@ public let CodeGenerators: [CodeGenerator] = [
b.setSuperProperty(propertyName, to: b.randomVariable())
},

CodeGenerator("ComputedSuperPropertyRetrievalGenerator", inContext: .method) { b in
let superType = b.currentSuperType()
let property = b.randomVariable()
b.getComputedSuperProperty(property)
},

CodeGenerator("ComputedSuperPropertyAssignmentGenerator", inContext: .method) { b in
let superType = b.currentSuperType()
let property = b.randomVariable()
b.setComputedSuperProperty(property, to: b.randomVariable())
},

CodeGenerator("SuperPropertyUpdateGenerator", inContext: .method) { b in
let superType = b.currentSuperType()
let propertyName = superType.randomProperty() ?? b.randomCustomPropertyName()
Expand Down
8 changes: 8 additions & 0 deletions Sources/Fuzzilli/FuzzIL/Instruction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,10 @@ extension Instruction: ProtobufConvertible {
$0.getSuperProperty = Fuzzilli_Protobuf_GetSuperProperty.with { $0.propertyName = op.propertyName }
case .setSuperProperty(let op):
$0.setSuperProperty = Fuzzilli_Protobuf_SetSuperProperty.with { $0.propertyName = op.propertyName }
case .getComputedSuperProperty(_):
$0.getComputedSuperProperty = Fuzzilli_Protobuf_GetComputedSuperProperty()
case .setComputedSuperProperty(_):
$0.setComputedSuperProperty = Fuzzilli_Protobuf_SetComputedSuperProperty()
case .updateSuperProperty(let op):
$0.updateSuperProperty = Fuzzilli_Protobuf_UpdateSuperProperty.with {
$0.propertyName = op.propertyName
Expand Down Expand Up @@ -1137,6 +1141,10 @@ extension Instruction: ProtobufConvertible {
op = GetSuperProperty(propertyName: p.propertyName)
case .setSuperProperty(let p):
op = SetSuperProperty(propertyName: p.propertyName)
case .getComputedSuperProperty(_):
op = GetComputedSuperProperty()
case .setComputedSuperProperty(_):
op = SetComputedSuperProperty()
case .updateSuperProperty(let p):
op = UpdateSuperProperty(propertyName: p.propertyName, operator: try convertEnum(p.op, BinaryOperator.allCases))
case .explore(let p):
Expand Down
1 change: 1 addition & 0 deletions Sources/Fuzzilli/FuzzIL/JSTyper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,7 @@ public struct JSTyper: Analyzer {
// For now we treat this as .anything
case .getElement,
.getComputedProperty,
.getComputedSuperProperty,
.callComputedMethod,
.callComputedMethodWithSpread:
set(instr.output, .anything)
Expand Down
17 changes: 17 additions & 0 deletions Sources/Fuzzilli/FuzzIL/JsOperations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1731,6 +1731,23 @@ final class SetSuperProperty: JsOperation {
}
}

final class SetComputedSuperProperty: JsOperation {
override var opcode: Opcode { .setComputedSuperProperty(self) }

init() {
super.init(numInputs: 2, requiredContext: [.javascript, .method])
}
}

final class GetComputedSuperProperty: JsOperation {
override var opcode: Opcode { .getComputedSuperProperty(self) }

init() {
super.init(numInputs: 1, numOutputs: 1, requiredContext: [.javascript, .method])
}
}


final class UpdateSuperProperty: JsOperation {
override var opcode: Opcode { .updateSuperProperty(self) }

Expand Down
2 changes: 2 additions & 0 deletions Sources/Fuzzilli/FuzzIL/Opcodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ enum Opcode {
case callPrivateMethod(CallPrivateMethod)
case getSuperProperty(GetSuperProperty)
case setSuperProperty(SetSuperProperty)
case getComputedSuperProperty(GetComputedSuperProperty)
case setComputedSuperProperty(SetComputedSuperProperty)
case updateSuperProperty(UpdateSuperProperty)
case beginIf(BeginIf)
case beginElse(BeginElse)
Expand Down
6 changes: 6 additions & 0 deletions Sources/Fuzzilli/Lifting/FuzzILLifter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,12 @@ public class FuzzILLifter: Lifter {
case .setSuperProperty(let op):
w.emit("SetSuperProperty '\(op.propertyName)', \(input(0))")

case .getComputedSuperProperty(_):
w.emit("\(output()) <- GetComputedSuperProperty \(input(0))")

case .setComputedSuperProperty(_):
w.emit("SetComputedSuperProperty \(input(0)), \(input(1))")

case .updateSuperProperty(let op):
w.emit("UpdateSuperProperty '\(op.propertyName)', '\(op.op.token)', \(input(0))")

Expand Down
9 changes: 9 additions & 0 deletions Sources/Fuzzilli/Lifting/JavaScriptLifter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,15 @@ public class JavaScriptLifter: Lifter {
let VALUE = input(0)
w.emit("super.\(PROPERTY) = \(VALUE);")

case .getComputedSuperProperty(_):
let expr = MemberExpression.new() + "super[" + input(0).text + "]"
w.assign(expr, to: instr.output)

case .setComputedSuperProperty(_):
let PROPERTY = input(0).text
let VALUE = input(1)
w.emit("super[\(PROPERTY)] = \(VALUE);")

case .updateSuperProperty(let op):
let PROPERTY = op.propertyName
let VALUE = input(0)
Expand Down
60 changes: 60 additions & 0 deletions Sources/Fuzzilli/Protobuf/operations.pb.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1981,6 +1981,26 @@ public struct Fuzzilli_Protobuf_SetSuperProperty {
public init() {}
}

public struct Fuzzilli_Protobuf_GetComputedSuperProperty {
// 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_SetComputedSuperProperty {
// 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_UpdateSuperProperty {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
Expand Down Expand Up @@ -2625,6 +2645,8 @@ extension Fuzzilli_Protobuf_UpdatePrivateProperty: @unchecked Sendable {}
extension Fuzzilli_Protobuf_CallPrivateMethod: @unchecked Sendable {}
extension Fuzzilli_Protobuf_GetSuperProperty: @unchecked Sendable {}
extension Fuzzilli_Protobuf_SetSuperProperty: @unchecked Sendable {}
extension Fuzzilli_Protobuf_GetComputedSuperProperty: @unchecked Sendable {}
extension Fuzzilli_Protobuf_SetComputedSuperProperty: @unchecked Sendable {}
extension Fuzzilli_Protobuf_UpdateSuperProperty: @unchecked Sendable {}
extension Fuzzilli_Protobuf_LoadNewTarget: @unchecked Sendable {}
extension Fuzzilli_Protobuf_Explore: @unchecked Sendable {}
Expand Down Expand Up @@ -6633,6 +6655,44 @@ extension Fuzzilli_Protobuf_SetSuperProperty: SwiftProtobuf.Message, SwiftProtob
}
}

extension Fuzzilli_Protobuf_GetComputedSuperProperty: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".GetComputedSuperProperty"
public static let _protobuf_nameMap = SwiftProtobuf._NameMap()

public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let _ = try decoder.nextFieldNumber() {
}
}

public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
try unknownFields.traverse(visitor: &visitor)
}

public static func ==(lhs: Fuzzilli_Protobuf_GetComputedSuperProperty, rhs: Fuzzilli_Protobuf_GetComputedSuperProperty) -> Bool {
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}

extension Fuzzilli_Protobuf_SetComputedSuperProperty: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".SetComputedSuperProperty"
public static let _protobuf_nameMap = SwiftProtobuf._NameMap()

public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let _ = try decoder.nextFieldNumber() {
}
}

public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
try unknownFields.traverse(visitor: &visitor)
}

public static func ==(lhs: Fuzzilli_Protobuf_SetComputedSuperProperty, rhs: Fuzzilli_Protobuf_SetComputedSuperProperty) -> Bool {
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}

extension Fuzzilli_Protobuf_UpdateSuperProperty: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".UpdateSuperProperty"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
Expand Down
6 changes: 6 additions & 0 deletions Sources/Fuzzilli/Protobuf/operations.proto
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,12 @@ message SetSuperProperty {
string propertyName = 1;
}

message GetComputedSuperProperty {
}

message SetComputedSuperProperty {
}

message UpdateSuperProperty {
string propertyName = 1;
BinaryOperator op = 2;
Expand Down
Loading

0 comments on commit 5696921

Please sign in to comment.