Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Sources/Fuzzilli/FuzzIL/JSTyper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,8 @@ public struct JSTyper: Analyzer {
.UnRShift:
return maybeBigIntOr(.integer)
case .LogicAnd,
.LogicOr:
.LogicOr,
.NullCoalesce:
return state.type(of: inputs[0]) | state.type(of: inputs[1])
}
}
Expand Down
2 changes: 2 additions & 0 deletions Sources/Fuzzilli/FuzzIL/JsOperations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1403,6 +1403,8 @@ public enum BinaryOperator: String, CaseIterable {
case RShift = ">>"
case Exp = "**"
case UnRShift = ">>>"
// Nullish coalescing operator (??)
case NullCoalesce = "??"

var token: String {
return self.rawValue
Expand Down
11 changes: 7 additions & 4 deletions Sources/Fuzzilli/Lifting/JavaScriptExploreLifting.swift
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,7 @@ struct JavaScriptExploreLifting {
//
function exploreObject(o) {
if (o === null) {
// Can't do anything with null.
return NO_ACTION;
return exploreNullish(o);
}

// TODO: Add special handling for ArrayBuffers: most of the time, wrap these into a Uint8Array to be able to modify them.
Expand Down Expand Up @@ -405,6 +404,11 @@ struct JavaScriptExploreLifting {
return action;
}

function exploreNullish(v) {
// Best thing we can do with nullish values is a NullCoalescing (??) operation.
return new Action(OP_NULL_COALESCE, [exploredValueInput, Inputs.randomArgument()])
}

// Explores the given value and returns an action to perform on it.
function exploreValue(id, v) {
if (isObject(v)) {
Expand All @@ -422,8 +426,7 @@ struct JavaScriptExploreLifting {
} else if (isBoolean(v)) {
return exploreBoolean(v);
} else if (isUndefined(v)) {
// Can't do anything with undefined.
return NO_ACTION;
return exploreNullish(v);
} else {
throw "Unexpected value type: " + typeof v;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ struct JavaScriptRuntimeAssistedMutatorLifting {
const OP_LOGICAL_AND = 'LOGICAL_AND';
const OP_LOGICAL_OR = 'LOGICAL_OR';
const OP_LOGICAL_NOT = 'LOGICAL_NOT';
const OP_NULL_COALESCE = 'NULL_COALESCE';

const OP_BITWISE_AND = 'BITWISE_AND';
const OP_BITWISE_OR = 'BITWISE_OR';
Expand Down Expand Up @@ -511,6 +512,7 @@ struct JavaScriptRuntimeAssistedMutatorLifting {
[OP_LOGICAL_AND]: (inputs) => inputs[0] && inputs[1],
[OP_LOGICAL_OR]: (inputs) => inputs[0] || inputs[1],
[OP_LOGICAL_NOT]: (inputs) => !inputs[0],
[OP_NULL_COALESCE]: (inputs) => inputs[0] ?? inputs[1],
[OP_BITWISE_AND]: (inputs) => inputs[0] & inputs[1],
[OP_BITWISE_OR]: (inputs) => inputs[0] | inputs[1],
[OP_BITWISE_XOR]: (inputs) => inputs[0] ^ inputs[1],
Expand Down
3 changes: 3 additions & 0 deletions Sources/Fuzzilli/Mutators/RuntimeAssistedMutator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ public class RuntimeAssistedMutator: Mutator {
case LogicalAnd = "LOGICAL_AND"
case LogicalOr = "LOGICAL_OR"
case LogicalNot = "LOGICAL_NOT"
case NullCoalesce = "NULL_COALESCE"
case BitwiseAnd = "BITWISE_AND"
case BitwiseOr = "BITWISE_OR"
case BitwiseXor = "BITWISE_XOR"
Expand Down Expand Up @@ -385,6 +386,8 @@ extension RuntimeAssistedMutator.Action {
try translateBinaryOperation(.BitOr)
case .BitwiseXor:
try translateBinaryOperation(.Xor)
case .NullCoalesce:
try translateBinaryOperation(.NullCoalesce)
case .LeftShift:
try translateBinaryOperation(.LShift)
case .SignedRightShift:
Expand Down
Loading