diff --git a/Sources/FuzzilliCli/Profiles/ArkProfile.swift b/Sources/FuzzilliCli/Profiles/ArkProfile.swift index 0f6234dbda01b8f7a6cd2dfb3e030f94325258d8..9e498b4ff932dd0b31ba62cf0ff0701665d86726 100644 --- a/Sources/FuzzilliCli/Profiles/ArkProfile.swift +++ b/Sources/FuzzilliCli/Profiles/ArkProfile.swift @@ -27,9 +27,19 @@ fileprivate let RunNearStackLimitGenerator = CodeGenerator("RunNearStackLimitGen /// ArkTS Generators fileprivate let ArkTSObjectInstanceGenerator = ValueGenerator("ArkTSObjectInstanceGenerator") { b, n in - let builtin = chooseUniform(from: ["Stack", "HashMap", "HashSet", "LinkedList", "List", "ArrayList"]) + let builtin = chooseUniform(from: ["Stack", "HashMap", "HashSet", "LinkedList", "List", "ArrayList", "TreeMap", "TreeSet"]) let constructor = b.loadBuiltin(builtin) - b.construct(constructor) + if ["TreeMap", "TreeSet"].contains(builtin) && probability(0.2) { //custom comparator for TreeMap and TreeSet will be generated only in 20% of cases + let comparator = b.buildPlainFunction(with: .parameters(n: 2)) { args in + assert(args.count >= 2) + // The comparator is either ascending or descending with equal probability + let result = b.compare(args[0], with: args[1], using: chooseUniform(from: [.greaterThan, .lessThan])) + b.doReturn(result) + } + b.construct(constructor, withArgs: [comparator]) + } else { + b.construct(constructor) + } } /// ArkTS Collections Generators @@ -51,6 +61,10 @@ fileprivate let arkTSLinkedList = ILType.iterable + ILType.object(ofGroup: "Link fileprivate let arkTSList = ILType.iterable + ILType.object(ofGroup: "List", withProperties: ["length"], withMethods: ["add", "insert", "has", "get", "getLastIndexOf", "getIndexOf", "equal", "removeByIndex", "remove", "replaceAllElements", "forEach", "sort", "getSubList", "clear", "set", "convertToArray", "isEmpty", "getFirst", "getLast"]) /// Type of a ArkTS ArrayList object. fileprivate let arkTSArrayList = ILType.iterable + ILType.object(ofGroup: "ArrayList", withProperties: ["length"], withMethods: ["add", "insert", "has", "getIndexOf", "getLastIndexOf", "removeByIndex", "remove", "removeByRange", "replaceAllElements", "forEach", "sort", "subArrayList", "clear", "clone", "getCapacity", "convertToArray", "isEmpty", "increaseCapacityTo", "trimToCurrentLength"]) +/// Type of a ArkTS TreeMap object. +fileprivate let arkTSTreeMap = ILType.iterable + ILType.object(ofGroup: "TreeMap", withProperties: ["length"], withMethods: ["isEmpty", "hasKey", "hasValue", "get", "getFirstKey", "getLastKey", "setAll", "set", "remove", "getLowerKey", "getHigherKey", "replace", "clear", "keys", "values", "forEach", "entries"]) +/// Type of a ArkTS TreeSet object. +fileprivate let arkTSTreeSet = ILType.iterable + ILType.object(ofGroup: "TreeSet", withProperties: ["length"], withMethods: ["isEmpty", "has", "getFirstValue", "getLastValue", "add", "remove", "getLowerValue", "getHigherValue", "popFirst", "popLast", "clear", "values", "forEach", "entries"]) /// Tpye of a ArkTS CollectionsMap object fileprivate let collectionsMap = ILType.iterable + ILType.object(ofGroup: "SharedMap", withProperties: ["size"], withMethods: ["entries", "keys", "values", "clear", "delete", "forEach", "get", "has", "set"]) @@ -67,6 +81,10 @@ fileprivate let arkTSLinkedListConstructor = ILType.constructor([] => arkTSLinke fileprivate let arkTSListConstructor = ILType.constructor([] => arkTSList) /// Type of the ArkTS ArrayList constructor builtin. fileprivate let arkTSArrayListConstructor = ILType.constructor([] => arkTSArrayList) +/// Type of the ArkTS TreeMap constructor builtin. +fileprivate let arkTSTreeMapConstructor = ILType.constructor([.opt(.function([.anything, .anything] => .boolean))] => arkTSTreeMap) +/// Type of the ArkTS TreeSet constructor builtin. +fileprivate let arkTSTreeSetConstructor = ILType.constructor([.opt(.function([.anything, .anything] => .boolean))] => arkTSTreeSet) /// Type of the ArkTs CollectionsMap constructor builtin. fileprivate let collectionsMapConstructor = ILType.constructor([.object()] => collectionsMap) @@ -183,7 +201,7 @@ fileprivate let arkTSLinkedLists = ObjectGroup( ] ) -// ObjectGroup modelling ArkTS List objects +/// ObjectGroup modelling ArkTS List objects fileprivate let arkTSLists = ObjectGroup( name: "List", instanceType: arkTSList, @@ -213,7 +231,7 @@ fileprivate let arkTSLists = ObjectGroup( ] ) -// ObjectGroup modelling ArkTS ArrayList objects +/// ObjectGroup modelling ArkTS ArrayList objects fileprivate let arkTSArrayLists = ObjectGroup( name: "ArrayList", instanceType: arkTSArrayList, @@ -243,6 +261,59 @@ fileprivate let arkTSArrayLists = ObjectGroup( ] ) +/// ObjectGroup modelling ArkTS TreeMap objects +fileprivate let arkTSTreeMaps = ObjectGroup( + name: "TreeMap", + instanceType: arkTSTreeMap, + properties: [ + "length" : .number, + ], + methods: [ + "isEmpty" : [] => .boolean, + "hasKey" : [.anything] => .boolean, + "hasValue" : [.anything] => .boolean, + "get" : [.anything] => .anything, + "getFirstKey" : [] => .anything, + "getLastKey" : [] => .anything, + "setAll" : [.object(ofGroup: "TreeMap")] => .undefined, + "set" : [.anything, .anything] => .object(), + "remove" : [.anything] => .anything, + "getLowerKey" : [.anything] => .anything, + "getHigherKey" : [.anything] => .anything, + "replace" : [.anything, .anything] => .boolean, + "clear" : [] => .undefined, + "keys" : [] => .object(), //returns an iterator + "values" : [] => .object(), //returns an iterator + "forEach" : [.function([.opt(.anything), .opt(.anything), .opt(arkTSTreeMap)] => .undefined), .opt(.object())] => .undefined, + "entries" : [] => .object(), //returns an iterator + ] +) + +/// ObjectGroup modelling ArkTS TreeSet objects +fileprivate let arkTSTreeSets = ObjectGroup( + name: "TreeSet", + instanceType: arkTSTreeSet, + properties: [ + "length" : .number, + ], + methods: [ + "isEmpty" : [] => .boolean, + "has" : [.anything] => .boolean, + "getFirstValue" : [] => .anything, + "getLastValue" : [] => .anything, + "add" : [.anything] => .boolean, + "remove" : [.anything] => .boolean, + "getLowerValue" : [.anything] => .anything, + "getHigherValue" : [.anything] => .anything, + "popFirst" : [] => .anything, + "popLast" : [] => .anything, + "clear" : [] => .undefined, + "values" : [] => .object(), //returns an iterator + "forEach" : [.function([.opt(.anything), .opt(.anything), .opt(arkTSTreeSet)] => .undefined), .opt(.object())] => .undefined, + "entries" : [] => .object(), //returns an iterator + ] +) + let arkProfile = Profile( processArgs: { randomize in var args = [ @@ -266,6 +337,8 @@ let arkProfile = Profile( var LinkedList = arkPrivate.Load(arkPrivate.LinkedList); var List = arkPrivate.Load(arkPrivate.List); var ArrayList = arkPrivate.Load(arkPrivate.ArrayList); + var TreeMap = arkPrivate.Load(arkPrivate.TreeMap); + var TreeSet = arkPrivate.Load(arkPrivate.TreeSet); function bgc() { for(let i=0; i<0x10000; i+=1) {new String();} @@ -316,6 +389,8 @@ let arkProfile = Profile( "LinkedList" : arkTSLinkedListConstructor, "List" : arkTSListConstructor, "ArrayList" : arkTSArrayListConstructor, + "TreeMap" : arkTSTreeMapConstructor, + "TreeSet" : arkTSTreeSetConstructor, ], additionalObjectGroups: [ @@ -326,6 +401,8 @@ let arkProfile = Profile( arkTSLinkedLists, arkTSLists, arkTSArrayLists, + arkTSTreeMaps, + arkTSTreeSets, ], optionalPostProcessor: nil