Skip to content

Commit 7bd555e

Browse files
whendrik-cmdV8-internal LUCI CQ
authored andcommitted
Make setProperty a GuardableOperation
This patch makes setProperty inherit from GuardableOperation instead of JsOperation and adds guards in CodeGenerators using setProperty to prevent invalid programs. Bug: 40272934 Change-Id: Ib2d54fa42da6e4d17caf039d1e489472f079e497 Reviewed-on: https://chrome-internal-review.googlesource.com/c/v8/fuzzilli/+/8543120 Reviewed-by: Hendrik Wüthrich <whendrik@google.com> Commit-Queue: Hendrik Wüthrich <whendrik@google.com> Reviewed-by: Matthias Liedtke <mliedtke@google.com> Auto-Submit: Hendrik Wüthrich <whendrik@google.com>
1 parent 4b65707 commit 7bd555e

11 files changed

Lines changed: 42 additions & 19 deletions

File tree

Sources/Fuzzilli/Base/ProgramBuilder.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2314,8 +2314,8 @@ public class ProgramBuilder {
23142314
return emit(GetProperty(propertyName: name, isGuarded: isGuarded), withInputs: [object]).output
23152315
}
23162316

2317-
public func setProperty(_ name: String, of object: Variable, to value: Variable) {
2318-
emit(SetProperty(propertyName: name), withInputs: [object, value])
2317+
public func setProperty(_ name: String, of object: Variable, to value: Variable, guard isGuarded: Bool = false) {
2318+
emit(SetProperty(propertyName: name, isGuarded: isGuarded), withInputs: [object, value])
23192319
}
23202320

23212321
public func updateProperty(_ name: String, of object: Variable, with value: Variable, using op: BinaryOperator) {

Sources/Fuzzilli/CodeGen/CodeGenerators.swift

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -980,8 +980,9 @@ public let CodeGenerators: [CodeGenerator] = [
980980
assert(propertyType == .jsAnything || b.type(of: obj).properties.contains(propertyName))
981981
let value = b.randomVariable(forUseAs: propertyType)
982982

983-
// TODO: (here and below) maybe wrap in try catch if obj may be nullish?
984-
b.setProperty(propertyName, of: obj, to: value)
983+
let needGuard = b.type(of: obj).MayBe(.nullish)
984+
985+
b.setProperty(propertyName, of: obj, to: value, guard: needGuard)
985986
},
986987

987988
CodeGenerator("PropertyUpdateGenerator", inputs: .preferred(.object())) { b, obj in
@@ -1655,13 +1656,15 @@ public let CodeGenerators: [CodeGenerator] = [
16551656
},
16561657

16571658
CodeGenerator("PrototypeOverwriteGenerator", inputs: .preferred(.object(), .object())) { b, obj, proto in
1658-
b.setProperty("__proto__", of: obj, to: proto)
1659+
let needGuard = b.type(of: obj).MayBe(.nullish)
1660+
b.setProperty("__proto__", of: obj, to: proto, guard: needGuard)
16591661
},
16601662

16611663
CodeGenerator("CallbackPropertyGenerator", inputs: .preferred(.object(), .function())) { b, obj, callback in
16621664
// TODO add new callbacks like Symbol.toPrimitive?
16631665
let propertyName = chooseUniform(from: ["valueOf", "toString"])
1664-
b.setProperty(propertyName, of: obj, to: callback)
1666+
let needGuard = b.type(of: obj).MayBe(.nullish)
1667+
b.setProperty(propertyName, of: obj, to: callback, guard: needGuard)
16651668
},
16661669

16671670
CodeGenerator("MethodCallWithDifferentThisGenerator", inputs: .preferred(.object(), .object())) { b, obj, this in
@@ -1724,7 +1727,9 @@ public let CodeGenerators: [CodeGenerator] = [
17241727
// (Probably) grow
17251728
newLength = b.loadInt(b.randomIndex())
17261729
}
1727-
b.setProperty("length", of: obj, to: newLength)
1730+
1731+
let needGuard = b.type(of: obj).MayBe(.nullish)
1732+
b.setProperty("length", of: obj, to: newLength, guard: needGuard)
17281733
},
17291734

17301735
// Tries to change the element kind of an array

Sources/Fuzzilli/Compiler/Compiler.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,7 @@ public class JavaScriptCompiler {
691691
if let op = assignmentOperator {
692692
emit(UpdateProperty(propertyName: name, operator: op), withInputs: [object, rhs])
693693
} else {
694-
emit(SetProperty(propertyName: name), withInputs: [object, rhs])
694+
emit(SetProperty(propertyName: name, isGuarded: memberExpression.isOptional), withInputs: [object, rhs])
695695
}
696696
case .expression(let expr):
697697
if case .numberLiteral(let literal) = expr.expression, let index = Int64(exactly: literal.value) {

Sources/Fuzzilli/FuzzIL/Instruction.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,10 @@ extension Instruction: ProtobufConvertible {
708708
$0.isGuarded = op.isGuarded
709709
}
710710
case .setProperty(let op):
711-
$0.setProperty = Fuzzilli_Protobuf_SetProperty.with { $0.propertyName = op.propertyName }
711+
$0.setProperty = Fuzzilli_Protobuf_SetProperty.with {
712+
$0.propertyName = op.propertyName
713+
$0.isGuarded = op.isGuarded
714+
}
712715
case .updateProperty(let op):
713716
$0.updateProperty = Fuzzilli_Protobuf_UpdateProperty.with {
714717
$0.propertyName = op.propertyName
@@ -1920,7 +1923,7 @@ extension Instruction: ProtobufConvertible {
19201923
case .getProperty(let p):
19211924
op = GetProperty(propertyName: p.propertyName, isGuarded: p.isGuarded)
19221925
case .setProperty(let p):
1923-
op = SetProperty(propertyName: p.propertyName)
1926+
op = SetProperty(propertyName: p.propertyName, isGuarded: p.isGuarded)
19241927
case .updateProperty(let p):
19251928
op = UpdateProperty(propertyName: p.propertyName, operator: try convertEnum(p.op, BinaryOperator.allCases))
19261929
case .deleteProperty(let p):

Sources/Fuzzilli/FuzzIL/JsOperations.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ class GuardableOperation: JsOperation {
6969
return GetProperty(propertyName: op.propertyName, isGuarded: true)
7070
case .deleteProperty(let op):
7171
return DeleteProperty(propertyName: op.propertyName, isGuarded: true)
72+
case .setProperty(let op):
73+
return SetProperty(propertyName: op.propertyName, isGuarded: true)
7274
case .getElement(let op):
7375
return GetElement(index: op.index, isGuarded: true)
7476
case .deleteElement(let op):
@@ -111,6 +113,8 @@ class GuardableOperation: JsOperation {
111113
return GetProperty(propertyName: op.propertyName, isGuarded: false)
112114
case .deleteProperty(let op):
113115
return DeleteProperty(propertyName: op.propertyName, isGuarded: false)
116+
case .setProperty(let op):
117+
return SetProperty(propertyName: op.propertyName, isGuarded: false)
114118
case .getElement(let op):
115119
return GetElement(index: op.index, isGuarded: false)
116120
case .deleteElement(let op):
@@ -1012,14 +1016,14 @@ final class GetProperty: GuardableOperation {
10121016
}
10131017
}
10141018

1015-
final class SetProperty: JsOperation {
1019+
final class SetProperty: GuardableOperation {
10161020
override var opcode: Opcode { .setProperty(self) }
10171021

10181022
let propertyName: String
10191023

1020-
init(propertyName: String) {
1024+
init(propertyName: String, isGuarded: Bool) {
10211025
self.propertyName = propertyName
1022-
super.init(numInputs: 2, attributes: .isMutable)
1026+
super.init(isGuarded: isGuarded, numInputs: 2, attributes: .isMutable)
10231027
}
10241028
}
10251029

Sources/Fuzzilli/Lifting/FuzzILLifter.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,8 @@ public class FuzzILLifter: Lifter {
328328
w.emit("\(output()) <- \(opcode) \(input(0)), '\(op.propertyName)'")
329329

330330
case .setProperty(let op):
331-
w.emit("SetProperty \(input(0)), '\(op.propertyName)', \(input(1))")
331+
let opcode = op.isGuarded ? "SetProperty (guarded)" : "SetProperty"
332+
w.emit("\(opcode) \(input(0)), '\(op.propertyName)', \(input(1))")
332333

333334
case .updateProperty(let op):
334335
w.emit("UpdateProperty \(input(0)), '\(op.op.token)', \(input(1))")

Sources/Fuzzilli/Mutators/FixupMutator.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ public class FixupMutator: RuntimeAssistedMutator {
147147
case .deleteProperty(let op):
148148
maybeFixup(instr, performing: .DeleteProperty, guarded: op.isGuarded, withInputs: [.argument(index: 0), .string(value: op.propertyName)], with: b)
149149

150+
case .setProperty(let op):
151+
maybeFixup(instr, performing: .SetProperty, guarded: op.isGuarded, withInputs: [.argument(index: 0), .string(value: op.propertyName)], with: b)
152+
150153
case .getElement(let op):
151154
maybeFixup(instr, performing: .GetProperty, guarded: op.isGuarded, withInputs: [.argument(index: 0), .int(value: op.index)], with: b)
152155

Sources/Fuzzilli/Mutators/OperationMutator.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ public class OperationMutator: BaseInstructionMutator {
117117
newOp = CreateArrayWithSpread(spreads: spreads)
118118
case .getProperty(let op):
119119
newOp = GetProperty(propertyName: b.randomPropertyName(), isGuarded: op.isGuarded)
120-
case .setProperty(_):
121-
newOp = SetProperty(propertyName: b.randomPropertyName())
120+
case .setProperty(let op):
121+
newOp = SetProperty(propertyName: b.randomPropertyName(), isGuarded: op.isGuarded)
122122
case .updateProperty(_):
123123
newOp = UpdateProperty(propertyName: b.randomPropertyName(), operator: chooseUniform(from: BinaryOperator.allCases))
124124
case .deleteProperty(let op):

Sources/Fuzzilli/Mutators/RuntimeAssistedMutator.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,12 +335,11 @@ extension RuntimeAssistedMutator.Action {
335335
b.getComputedProperty(property, of: o, guard: isGuarded)
336336
}
337337
case .SetProperty:
338-
assert(!isGuarded)
339338
let o = try translateInput(0)
340339
let v = try translateInput(2)
341340
switch try getInput(1) {
342341
case .string(let propertyName):
343-
b.setProperty(propertyName, of: o, to: v)
342+
b.setProperty(propertyName, of: o, to: v, guard: isGuarded)
344343
case .int(let index):
345344
b.setElement(index, of: o, to: v)
346345
default:

Sources/Fuzzilli/Protobuf/operations.pb.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2409,6 +2409,8 @@ public struct Fuzzilli_Protobuf_SetProperty: Sendable {
24092409

24102410
public var propertyName: String = String()
24112411

2412+
public var isGuarded: Bool = false
2413+
24122414
public var unknownFields = SwiftProtobuf.UnknownStorage()
24132415

24142416
public init() {}
@@ -7744,7 +7746,7 @@ extension Fuzzilli_Protobuf_GetProperty: SwiftProtobuf.Message, SwiftProtobuf._M
77447746

77457747
extension Fuzzilli_Protobuf_SetProperty: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
77467748
public static let protoMessageName: String = _protobuf_package + ".SetProperty"
7747-
public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}propertyName\0")
7749+
public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}propertyName\0\u{1}isGuarded\0")
77487750

77497751
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
77507752
while let fieldNumber = try decoder.nextFieldNumber() {
@@ -7753,6 +7755,7 @@ extension Fuzzilli_Protobuf_SetProperty: SwiftProtobuf.Message, SwiftProtobuf._M
77537755
// enabled. https://github.com/apple/swift-protobuf/issues/1034
77547756
switch fieldNumber {
77557757
case 1: try { try decoder.decodeSingularStringField(value: &self.propertyName) }()
7758+
case 2: try { try decoder.decodeSingularBoolField(value: &self.isGuarded) }()
77567759
default: break
77577760
}
77587761
}
@@ -7762,11 +7765,15 @@ extension Fuzzilli_Protobuf_SetProperty: SwiftProtobuf.Message, SwiftProtobuf._M
77627765
if !self.propertyName.isEmpty {
77637766
try visitor.visitSingularStringField(value: self.propertyName, fieldNumber: 1)
77647767
}
7768+
if self.isGuarded != false {
7769+
try visitor.visitSingularBoolField(value: self.isGuarded, fieldNumber: 2)
7770+
}
77657771
try unknownFields.traverse(visitor: &visitor)
77667772
}
77677773

77687774
public static func ==(lhs: Fuzzilli_Protobuf_SetProperty, rhs: Fuzzilli_Protobuf_SetProperty) -> Bool {
77697775
if lhs.propertyName != rhs.propertyName {return false}
7776+
if lhs.isGuarded != rhs.isGuarded {return false}
77707777
if lhs.unknownFields != rhs.unknownFields {return false}
77717778
return true
77727779
}

0 commit comments

Comments
 (0)