├── sample-out.html ├── deletey └── deletefuzz.js ├── runtime └── init.js ├── mathy ├── init.js └── mathfuzz.js ├── regexy ├── init.js └── regexfuzz.js ├── stringy ├── init.js └── stringfuzz.js ├── enumy ├── init.js └── enumfuzz.js ├── functiony ├── init.js └── functionfuzz.js ├── classy ├── init.js └── classfuzz.js ├── arrayy ├── init.js └── arrayfuzz.js ├── README.md ├── domy └── init.js ├── gettersettery └── getter │ └── getterfuzz.js └── lucky-jsfuzz-chrome.html /sample-out.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leonwxqian/lucky-js-fuzz/HEAD/sample-out.html -------------------------------------------------------------------------------- /deletey/deletefuzz.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leonwxqian/lucky-js-fuzz/HEAD/deletey/deletefuzz.js -------------------------------------------------------------------------------- /runtime/init.js: -------------------------------------------------------------------------------- 1 | function initVariantRuntime() 2 | { 3 | g_tankVariant_runtime.push("x_init_runtimevar"); 4 | g_initScript += "var x_init_runtimevar = this\n"; 5 | } -------------------------------------------------------------------------------- /mathy/init.js: -------------------------------------------------------------------------------- 1 | 2 | function initVariantTankMathy() 3 | { 4 | for(var i = 0; i < g_variant_tank_count_mathy; i++) 5 | { 6 | g_tankVariant_mathy[i] = "v_mathy_" + i.toString(); 7 | g_initScript += "try{ var v_mathy_" + i.toString() + " = " + generateRndPureNumber() + ";} catch(e) {} \n"; 8 | } 9 | } -------------------------------------------------------------------------------- /regexy/init.js: -------------------------------------------------------------------------------- 1 | function initVariantRegexy() 2 | { 3 | for(var i = 0; i < g_variant_tank_count_regexy; i++) 4 | { 5 | g_tankVariant_regexy[i] = "v_regexy_" + i.toString(); 6 | g_initScript += "try { var v_regexy_" + i.toString() + " = " + generateOneRegex(false) + ";} catch(e) {} \n"; 7 | } 8 | } -------------------------------------------------------------------------------- /stringy/init.js: -------------------------------------------------------------------------------- 1 | 2 | function initVariantStringy() 3 | { 4 | for(var i = 0; i < g_variant_tank_count_stringy; i++) 5 | { 6 | g_tankVariant_stringy[i] = "v_stringy_" + i.toString(); 7 | g_initScript += "try{ var v_stringy_" + i.toString() + " = \"" + generateOneString() + "\";} catch(e) {} \n"; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /enumy/init.js: -------------------------------------------------------------------------------- 1 | 2 | function initVariantEnumeratory() 3 | { 4 | for(var i = 0; i < g_variant_tank_count_enumeratory; i++) 5 | { 6 | g_tankVariant_enumeratory[i] = "v_enumy_" + i.toString(); 7 | g_initScript += "try { var v_enumy_" + i.toString() + " = new Enumerator([" + generateOneArrayInitTable() + "]);} catch(e) {} \n"; 8 | g_initScript += "try { v_enumy_" + i.toString() + ".moveFirst();} catch(e) {} \n"; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /enumy/enumfuzz.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | function generateOneEnumStatement() 4 | { 5 | var rndItem = g_tankVariant_enumeratory[rand(g_tankVariant_enumeratory.length)]; 6 | 7 | switch(rand(4)) 8 | { 9 | case 0: 10 | return rndItem + ".atEnd()"; 11 | case 1: 12 | return rndItem + ".item()"; 13 | case 2: 14 | return rndItem + ".moveFirst()"; 15 | case 3: 16 | return rndItem + ".moveNext()"; 17 | } 18 | 19 | } 20 | 21 | function enumFuzz() 22 | { 23 | for(var i =0; i < 10; i++) 24 | stmtPush(generateOneEnumStatement()); 25 | } 26 | -------------------------------------------------------------------------------- /functiony/init.js: -------------------------------------------------------------------------------- 1 | 2 | function initVariantFunctiony() 3 | { 4 | for(var i = 0; i < g_variant_tank_count_functiony; i++) 5 | { 6 | g_tankVariant_functiony[i] = "v_functiony_" + i.toString(); 7 | g_initScript += "function v_functiony_" + i.toString() + "() {\n\ttry{" + generateClassFunctionStatements(5) + "}catch(e){}\n};\n"; 8 | 9 | //this function (a){return ..} was provided to use for iterators. 10 | g_tankVariant_functiony_iterator[i] = "v_iteratory_" + i.toString(); 11 | 12 | var rndTwoWayOp = getRndTwoWayOp(false); 13 | var attr1 = generateRndClassAttrVarFromTank(); 14 | var item1 = g_tankVariant_classyv[rand(g_tankVariant_classyv.length)]; 15 | 16 | g_initScript += "function v_iteratory_" + i.toString() + "(a) {\n\t" + 17 | "try{\r\n" + 18 | "return a " + rndTwoWayOp + attr1 + "." + item1 + 19 | "}catch(e){" + 20 | "return true;" + 21 | "}"+ 22 | "\n};\n"; 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /classy/init.js: -------------------------------------------------------------------------------- 1 | 2 | //attr of object是一组预设的属性值,用来做class fuzz用,当然你也可以让它变成其他的什么也好 3 | //在这里提前存储属性值的缘故是,之后可能会有频繁的操作读取,所以用固定的名字,可以更方便的让fuzzer取到正确属性。 4 | function initVariantAttrofobject() 5 | { 6 | for(let i = 0; i < g_variant_tank_count_attrofobject; i++) 7 | { 8 | //属性中生成的字符串没必要随机,这不会有什么大问题,7个字,足够小几率不重复就好。 9 | //加a是为了防止出现什么鬼数字开头的情况 10 | g_tankVariant_attrofobject.push("a" + generateRandomChar(7, true)); 11 | } 12 | } 13 | 14 | function initVariantClassy() 15 | { 16 | for(var i = 0; i < g_variant_tank_count_classy; i++) 17 | { 18 | g_tankVariant_classyf[i] = "f_classy_" + i.toString(); 19 | g_tankVariant_classyv[i] = "v_classy_" + i.toString(); 20 | g_initScript += "function f_classy_" + i.toString() + 21 | "(input) {\n\tthis.fuzzy = input;\n};\n" + 22 | "f_classy_" + i.toString() + 23 | ".prototype.fuzz = function() {\n\t\t\ttry{" + 24 | generateClassFunctionStatements(12) + 25 | ";'warning2';return fuzzy;}catch(e){}\n}\n"; 26 | 27 | g_initScript += "try{ var v_classy_" + i.toString() + " = new f_classy_" + i.toString() +"(" + genClassyInitParameter() + ");} catch(e) {}" 28 | //call v_classy_X.fuzz() anytime. 29 | } 30 | } -------------------------------------------------------------------------------- /functiony/functionfuzz.js: -------------------------------------------------------------------------------- 1 | 2 | function generateOneFunction(executeAfterDeclaration, argCount, needTryCatch) 3 | { 4 | var out; 5 | var argList = ''; 6 | var callList = ''; 7 | for(var i = 0; i < argCount; i++) 8 | { 9 | if(i != argCount -1) 10 | { 11 | argList += "tmp_arg_" + i.toString() + ", " 12 | callList += '1, ' 13 | } 14 | else 15 | { 16 | argList += "tmp_arg_" + i.toString() 17 | callList += '1' 18 | } 19 | } 20 | 21 | if(needTryCatch) 22 | { 23 | if(executeAfterDeclaration) 24 | out = '(function (' + argList + '){\ntry{'; 25 | else 26 | out = 'function (' + argList + '){\ntry{'; 27 | } 28 | else 29 | { 30 | if(executeAfterDeclaration) 31 | out = '(function (' + argList + '){\n'; 32 | else 33 | out = 'function (' + argList + '){\n'; 34 | } 35 | 36 | 37 | var stmtCount = 1 + rand(15); 38 | out += generateClassFunctionStatements(stmtCount); 39 | 40 | if(needTryCatch) 41 | { 42 | if(executeAfterDeclaration) 43 | out += "\n}catch(e){}})(" + callList + ");\n"; 44 | else 45 | out += "\n}catch(e){}};\n"; 46 | 47 | } 48 | else 49 | { 50 | if(executeAfterDeclaration) 51 | out += "\n})(" + callList + ");\n"; 52 | else 53 | out += "\n};\n"; 54 | } 55 | 56 | return out; 57 | } 58 | 59 | function functionFuzz() 60 | { 61 | for(var i=0; i < 10; i++) 62 | stmtPush(generateOneFunction(rand(2), rand(2), true)); 63 | } -------------------------------------------------------------------------------- /arrayy/init.js: -------------------------------------------------------------------------------- 1 | 2 | function initVariantArrayy() 3 | { 4 | for(var i = 0; i < g_variant_tank_count_arrayy; i++) 5 | { 6 | g_tankVariant_arrayy[i] = "v_arrayy_" + i.toString(); 7 | g_initScript += "try{ var v_arrayy_" + i.toString() + " = new Array(" + generateOneArrayInitTable() + "); } catch(e) {} \n"; 8 | } 9 | } 10 | 11 | 12 | 13 | function generateOneArrayInitTable() 14 | { 15 | var out = ''; 16 | var rndOp = rand(3); 17 | switch(rndOp) 18 | { 19 | case 0: 20 | return ''; 21 | case 1: 22 | return generateRndNumber(); 23 | case 2: 24 | { 25 | //generate an init-list. 26 | //this could be ANY type, feel excited? 27 | 28 | var maxItems = 2 + rand(13); 29 | var func = function(){ 30 | switch(rand(3)) 31 | { 32 | case 0: 33 | out += generateOneMathStatement('', 0, 2); 34 | break; 35 | case 1: 36 | out += generateOneRegex(false); 37 | break; 38 | case 2: 39 | //out += "\"" + generateOneStringStatement(true) + "\""; 40 | out += generateOneStringStatement(true) ; 41 | break; 42 | //todo : add more more more! 43 | // funcs or whatever! 44 | } 45 | } 46 | 47 | for(var i=0; i < maxItems; i++) 48 | { 49 | func(); 50 | out += ","; 51 | } 52 | 53 | func(); 54 | } 55 | } 56 | if(out[out.length - 1] == ',') out=out+"0"; 57 | if(out[0] == ',') out = '0' + out; 58 | return out; 59 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # lucky-js-fuzz 2 | Html that generates random js statements then fuzz in the web-browser. 3 | 4 | 5 | **Usage:** 6 | 7 | a) put all of those files under a web server 8 | 9 | b) visit lucky-jsfuzz-chrome.html 10 | 11 | please notice the last line of lucky-jsfuzz-chrome.html: outputAllThingsHTMLFormat(false); 12 | if you want to run the script instantly in the web-browser, you should change the arugment 'false' to 'true'. 13 | 14 | 15 | **Sample output:** 16 | 17 | Please check sample_out.html 18 | 19 | This html file was generated by every type of output limited to `3`, recommend value is `12`. 20 | 21 | **Contact me:** 22 | 23 | Wenxiang Qian (Twitter: @leonwxqian / Weibo: @leonwxqian) of Tencent Blade Team, leonwxqian#gmail.com or #qq.com. 24 | 25 | Blog: http://nul.pw 26 | 27 | **Hacks to use this smoother** 28 | 29 | When you use this, there should **obviously** with some problems like: 30 | * When render is hanged, the page won't redirect to new seed. => maybe you need to write an extension or something to force it reload. 31 | * When there's an out-of-memory, the page will die and cause some false alarms if you have monitored the status of page. => a simple hack: modify chromium , when oom is happen, reload current page. Same thing for page hang. 32 | * Many oom are caused by RegEx operations, and hang are caused by dom insertion, you can comment out these two fuzzers to increase the fuzzing speed if you don't want to fuzz them. 33 | 34 | Of course you can use this as a functional fuzzer, however, this is just designed to be a part of fuzzing system which means this is lacking of some functions which couldn't be done by just javascript. For example: crash monitoring, binary level error handling, crash reporting... You should add them by yourself, FF/Chromium/V8 is open source so I think you can do it easily. :) 35 | 36 | Happy hacking & fuzzing! 37 | 38 | 39 | 40 | **PS** 41 | 42 | I am not a pro on writing Javascript, and this fuzzer was written in a hurry. So the project is written in a very old and ugly style. 43 | 44 | It was formerly going to be used for fuzzing NScript, a script evaluation engine used in the Windows Defender, so there're only basic data type supported here. I will update often as I am prepare to use this to do more fuzzing work in the future. 45 | -------------------------------------------------------------------------------- /domy/init.js: -------------------------------------------------------------------------------- 1 | var g_list_domlist = new Array("a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "basefont", "bdi", "bdo", "bgsound", "big", "blink", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "command", "content", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt", "element", "em", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", "frame", "frameset", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", "hr", "html", "i", "iframe", "image", "img", "input", "ins", "isindex", "kbd", "keygen", "label", "legend", "li", "link", "listing", "main", "map", "mark", "marquee", "menu", "menuitem", "meta", "meter", "multicol", "nav", "nobr", "noembed", "noframes", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "picture", "plaintext", "pre", "progress", "q", "rp", "rt", "rtc", "ruby", "s", "samp", "script", "section", "select", "shadow", "slot", "small", "Source", "spacer", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "tt", "u", "ul", "var", "video", "wbr", "xmp"); 2 | 3 | function generateRndDomVarFromTank() 4 | { 5 | return g_list_domlist[parseInt(rand(g_list_domlist.length))]; 6 | } 7 | 8 | function generateRndDomVarFromIndex(arr, maxIndex) 9 | { 10 | return arr[parseInt(rand(maxIndex))]; 11 | } 12 | 13 | 14 | function initVariantAttrofdom() 15 | { 16 | for(let i = 0; i < g_variant_tank_count_attrofobject; i++) 17 | { 18 | //set attr 19 | //todo: add things here. 20 | //you sohuld give the initial attribute of the given dom here. 21 | //set css 22 | //and more css rules here. 23 | } 24 | } 25 | 26 | function initVariantDomy() 27 | { 28 | for(var i = 0; i < g_variant_tank_count_domy; i++) 29 | { 30 | g_tankVariant_domy[i] = "v_domy_" + i.toString(); 31 | g_initScript += "var " + g_tankVariant_domy[i] + "= document.createElement(\"" + generateRndDomVarFromTank() + "\");\r\n"; 32 | 33 | var times = 1 + rand(4); 34 | let j = 0; 35 | while(j++ < times) 36 | { 37 | if(i >= 1) 38 | g_initScript += "try {\r\n" + generateRndDomVarFromIndex(g_tankVariant_domy, i) + ".appendChild(" + g_tankVariant_domy[i] + ");\r\n} catch(e) {} \r\n"; 39 | } 40 | } 41 | 42 | //finally attach those elements into the page. 43 | g_initScript += "try{ document.body.appendChild(v_domy_0); } catch(e) {}; \r\n"; 44 | } 45 | -------------------------------------------------------------------------------- /gettersettery/getter/getterfuzz.js: -------------------------------------------------------------------------------- 1 | /* 2 | 1. getWho : 3 | the subject of which we will modify the getter function with. 4 | this could be an usual object, such as o1 in "var o1 = [];" but can not be "undefined", 5 | 2. whichKey : 6 | set the key that we will access later. for ex. "k", we can access as o1["k"] or o1.k; 7 | */ 8 | function generateDefineGetterStmt(getWho, whichKey) 9 | { 10 | g_tankVariant_data_getaccessKeyTank.push(getWho); 11 | g_tankVariant_data_getaccessValueTank.push(whichKey); 12 | 13 | var out = getWho + ".__defineGetter__(\"" + whichKey + "\", function () {"; 14 | var maximumStmts = 4 + rand(5); 15 | 16 | var stmtCount = 1 + rand(15); 17 | out += generateClassFunctionStatements(stmtCount); 18 | out += "\r\nreturn " + getRndItemInGlobalTank(); 19 | out += "\r\n});\r\n"; 20 | 21 | out += getWho + "[\"" + whichKey + "\"];\r\n"; 22 | //access key_value pairs randomly later! 23 | return out; 24 | } 25 | 26 | function getRandomKeyValuePairStr() 27 | { 28 | var keyIndex = parseInt(rand(g_tankVariant_data_getaccessKeyTank.length)); 29 | return g_tankVariant_data_getaccessKeyTank[keyIndex] + "[\"" + g_tankVariant_data_getaccessValueTank[keyIndex] + "\"]"; 30 | } 31 | 32 | function getRandomKeyValuePairStr2() 33 | { 34 | var keyIndex = parseInt(rand(g_tankVariant_data_getaccessKeyTank.length)); 35 | return g_tankVariant_data_getaccessKeyTank[keyIndex] + "." + g_tankVariant_data_getaccessValueTank[keyIndex]; 36 | } 37 | 38 | 39 | //this was usually NOT a STATEMENT but only a FRAGMENT 40 | function generateOneRndGetFragment() 41 | { 42 | return getRandomKeyValuePairStr(); 43 | } 44 | 45 | function defineOneGetter() 46 | { 47 | var g_prototypes_can_be_set = new Array( 48 | "this", "Object.prototype", "Array.prototype", "String.prototype", "Number.prototype", "Function.prototype", "Map.prototype", "Set.prototype", 49 | "ArrayBuffer.prototype", "DataView.prototype", "Promise.prototype" 50 | ); 51 | 52 | var rndSubject = g_prototypes_can_be_set[parseInt(rand(g_prototypes_can_be_set.length))]; 53 | var rndObject = g_tankVariant_attrofobject[parseInt(rand(g_tankVariant_attrofobject.length))]; 54 | return generateDefineGetterStmt(rndSubject, rndObject); 55 | 56 | } 57 | 58 | //this shall be in init.js but we got a problem about sequence, so we just put it here temporarily 59 | function initGetterInitFuzzer() 60 | { 61 | for(var i = 0; i < g_variant_tank_count_getter; i++) 62 | g_initScript += defineOneGetter() + "\r\n"; 63 | } 64 | 65 | function fuzzGetter() 66 | { 67 | var maximum = 4 + rand(20); 68 | for(var i = 0; i < maximum; i++) 69 | g_fuzzingStmtTank.push( "try{" + generateOneRndGetFragment() + "} catch(e){}; \r\n" ); 70 | } 71 | -------------------------------------------------------------------------------- /mathy/mathfuzz.js: -------------------------------------------------------------------------------- 1 | 2 | //parse one rule and generate one fragment. 3 | function parseOneFragRuleMathy(rule) 4 | { 5 | var pos = 0; 6 | var maximumArgCount = rule[1]; 7 | var tempTank = new Array(); 8 | var tankCount = 0; 9 | 10 | //rule[0] : return type 11 | //rule[1] : frag count 12 | //rule[2] : frag descriptor 13 | 14 | for(var i = 0, j = 0; i < maximumArgCount; i += 1, j += 2) 15 | { 16 | if(rule[2 + j] == NUMBER && rule[2 + j + 1] == CANT_BE_INSTANT_VAL) 17 | tempTank[tankCount++] = generateRndVarFromTank(); 18 | else if(rule[2 + j] == NUMBER && rule[2 + j + 1] == CAN_BE_INSTANT_VAL) 19 | tempTank[tankCount++] = generateRndNumber(); 20 | else if(rule[2 + j] == GENERAL_OBJECT && rule[2 + j + 1] == CANT_BE_INSTANT_VAL) 21 | tempTank[tankCount++] = generateRndVarFromTank(); 22 | else if(rule[2 + j] == GENERAL_OBJECT && rule[2 + j + 1] == CAN_BE_INSTANT_VAL) 23 | tempTank[tankCount++] = generateRndNumber(); 24 | else if(rule[2 + j] == COMMA_MULTILIST) 25 | tempTank[tankCount++] = generateOneMathStatement('', 0, 2); 26 | } 27 | 28 | var fragmentFormat = rule[j + 2]; 29 | for(var i = 1; i <= maximumArgCount; i++) 30 | { 31 | fragmentFormat = fragmentFormat.replace('[' + i.toString() + ']', tempTank[i - 1]); 32 | } 33 | 34 | return fragmentFormat; 35 | } 36 | 37 | function parseOneFragRuleMathyWithFragment1Arg(rule, value) 38 | { 39 | var pos = 0; 40 | var maximumArgCount = rule[1]; 41 | var tempTank = new Array(); 42 | var tankCount = 0; 43 | 44 | for(var i = 0, j = 0; i < maximumArgCount; i += 1, j += 2) 45 | { 46 | ; 47 | } 48 | 49 | var fragmentFormat = rule[j + 2]; 50 | for(var i = 1; i <= maximumArgCount; i++) 51 | { 52 | fragmentFormat = fragmentFormat.replace('[' + i.toString() + ']', value); 53 | } 54 | 55 | return fragmentFormat; 56 | } 57 | 58 | 59 | function generateOneMathStatement(originalStat, currentNestLevel, maxNestLevel) 60 | { 61 | var sStatement = originalStat; 62 | var sStatmentThisStep = ''; 63 | 64 | var iNestLevel = currentNestLevel; 65 | 66 | var currentStat = NONE; 67 | 68 | while((currentStat == NONE || currentStat == FRAGMENT) && iNestLevel < maxNestLevel) 69 | { 70 | sStatmentThisStep = ''; 71 | 72 | var rndOp = parseInt(rand(4)); 73 | var rule; 74 | var bCanNest = false; 75 | switch(rndOp) 76 | { 77 | case 0: 78 | //rule = g_ruleList_general_assignment[parseInt(rand(g_ruleList_general_assignment.length))]; 79 | 80 | //break; 81 | 82 | case 2: 83 | rule = g_ruleList_mathy[parseInt(rand(g_ruleList_mathy.length))]; 84 | break; 85 | case 1: 86 | 87 | //rule = g_ruleList_mathy_statement[parseInt(rand(g_ruleList_mathy_statement.length))]; 88 | //break; 89 | case 3: 90 | rule = g_funcList_mathy[parseInt(rand(g_funcList_mathy.length))]; 91 | bCanNest = true; 92 | break; 93 | } 94 | 95 | if(!bCanNest || iNestLevel >= maxNestLevel) 96 | { 97 | sStatmentThisStep = parseOneFragRuleMathy(rule); 98 | } 99 | else 100 | { 101 | iNestLevel++; 102 | sStatmentThisStep = generateOneMathStatement(sStatement, iNestLevel, maxNestLevel); 103 | sStatmentThisStep = parseOneFragRuleMathyWithFragment1Arg(rule, sStatmentThisStep); 104 | } 105 | 106 | if(bCanNest) 107 | sStatement = sStatmentThisStep; 108 | else if(sStatement.length > 0) 109 | sStatement = sStatement + ", " + sStatmentThisStep; 110 | else 111 | sStatement += sStatmentThisStep; 112 | 113 | currentStat = rule[rule.length - 1]; 114 | 115 | // 1/3 chance: stop generate statement 116 | //if(currentStat != NONE && rand(10) < 3) 117 | // break; 118 | } 119 | 120 | return sStatement; 121 | 122 | } 123 | 124 | function mathFuzz() 125 | { 126 | for(var i =0 ; i < 10; i++) 127 | stmtPush(generateOneMathStatement('', 0, 2)) 128 | } -------------------------------------------------------------------------------- /regexy/regexfuzz.js: -------------------------------------------------------------------------------- 1 | 2 | function generateRandomRegexMeta() 3 | { 4 | 5 | var meta = new Array('.','\\w','\\W','\\d','\\D','\\s','\\S','\\b','\\B','\\0','\\n','\\f','\\r','\\t','\\v','\\xxx','\\xdd','\\uxxxx'); 6 | var rndOne = meta[rand(meta.length)]; 7 | if(rndOne == '\\xxx') 8 | rndOne = '\\0' + rand(0xff).toString(8); 9 | else if(rndOne == '\\xdd') 10 | rndOne = '\\x' + rand(0xff).toString(16); 11 | else if(rndOne == '\\uxxxx') 12 | { 13 | rndOne = rand(0xffff).toString(16); 14 | rndOne = '0000'.substr(0, 4 - rndOne.length) + rndOne; 15 | rndOne = '\\u' + rndOne; 16 | } 17 | 18 | return rndOne; 19 | } 20 | 21 | 22 | function generateRandomIntRange(){ 23 | var p = parseInt(rand(10)); 24 | var q = parseInt(rand(10)); 25 | if(p < q) 26 | return p.toString() + "-" + q.toString(); 27 | else 28 | return q.toString() + "-" + p.toString(); //edge complains about p is lager than q 29 | } 30 | function min(p , q) 31 | { 32 | return p < q ? p : q 33 | } 34 | 35 | function max(p , q) 36 | { 37 | return p > q ? p : q 38 | } 39 | 40 | function generateRandomCharRange(){ 41 | var p = parseInt(rand(26)); 42 | var q = parseInt(rand(26)); 43 | var xcase = parseInt(rand(2)); 44 | var r = xcase ? 0x41 : 0x61; 45 | var s = xcase ? 0x41 : 0x61; //edge complains about case difference.... 46 | 47 | var minone = min(p, q); 48 | var maxone = max(p, q); 49 | return String.fromCharCode(minone + r) + "-" + String.fromCharCode(maxone + s); 50 | } 51 | 52 | function generateClassfier(noun) 53 | { 54 | var cf = rand(13); 55 | switch(cf) 56 | { 57 | case 0: 58 | return noun + "+"; 59 | case 1: 60 | return noun + "*"; 61 | case 2: 62 | return noun + "?"; 63 | case 3: 64 | return noun + "{" + rand(30).toString() + "}"; 65 | case 4: 66 | return noun + "{" + rand(65535).toString() + "}"; //edge complains number is too large.. 67 | case 5: 68 | var p = rand(30); 69 | var q = rand(30); 70 | return noun + "{" + min(p, q).toString() + "," + max(p, q).toString() + "}"; 71 | case 6: 72 | var p = rand(65535); 73 | var q = rand(65535); 74 | return noun + "{" + min(p, q).toString() + "," + max(p, q).toString() + "}"; 75 | case 7: 76 | return noun + "{" + rand(30).toString() + ",}"; 77 | case 8: 78 | return noun + "{" + rand(65535).toString() + ",}"; 79 | case 9: 80 | return noun + "$"; 81 | case 10: 82 | return "^" + noun; 83 | case 11: 84 | return "?=" + noun; //edge complains nothing before ?=... 85 | case 12: 86 | return "?!" + noun; 87 | } 88 | } 89 | 90 | function generateRegexRange(){ 91 | var type = rand(5); 92 | var output = '['; 93 | switch(type) 94 | { 95 | case 0: output += generateRandomChar(rand(10), false); break; 96 | case 1: output += '^' + generateRandomChar(rand(10), false); break; 97 | case 2: output += generateRandomIntRange(); break; 98 | case 3: output += generateRandomCharRange(); break; 99 | case 4: 100 | output = '('; 101 | var max = rand(5); 102 | for(var i=0; i < max; i++) 103 | output += generateRandomChar(rand(10), true) + '|'; 104 | output += generateRandomChar(rand(10), true) + ')'; 105 | return output; 106 | } 107 | output += ']'; 108 | return output; 109 | } 110 | 111 | 112 | function generateOneRegex(useAssignFormExplictly) 113 | { 114 | var out; 115 | 116 | var assignForm = rand(2) ? true : false; 117 | if(useAssignFormExplictly) 118 | assignForm = true; 119 | 120 | if(assignForm) 121 | out = '/'; 122 | else 123 | out = 'new RegExp(\"'; 124 | 125 | var randStep = 2 + rand(10); 126 | for(var i = 0; i < randStep; i++) 127 | { 128 | var tmp = generateClassfier(generateRegexRange()); 129 | if(tmp[0] == '?') tmp = 'o' + tmp; 130 | out += tmp; 131 | 132 | 133 | out += generateRandomChar(3, false); 134 | } 135 | 136 | if(assignForm) 137 | out += '/'; 138 | else 139 | out += "\", \""; 140 | 141 | switch(rand(3)) 142 | { 143 | case 0: 144 | out += 'g'; 145 | break; 146 | case 1: 147 | out += 'i'; 148 | break; 149 | case 2: 150 | out += 'm'; 151 | break; 152 | } 153 | 154 | if(!assignForm) 155 | out += "\")"; 156 | return out; 157 | } 158 | 159 | function generateRndRegexVarFromTank() 160 | { 161 | return g_tankVariant_regexy[parseInt(rand(g_tankVariant_regexy.length))]; 162 | } 163 | 164 | 165 | 166 | function regexFuzz() 167 | { 168 | //1. get one item from all tanks; 169 | //2. get rndOne from rndItemArray 170 | var strOut = ''; 171 | for(var i = 0; i < 10; i++) 172 | { 173 | var rndItemArray = g_alltanks[rand(g_alltanks.length)]; 174 | var rndOne = rndItemArray[rand(rndItemArray.length)]; 175 | var rndRegex = g_tankVariant_regexy[rand(g_tankVariant_regexy.length)]; 176 | 177 | //todo: pass these return value to a random object. 178 | switch(rand(2)) 179 | { 180 | case 0: 181 | strOut += rndRegex + ".test(" + rndOne + ");\n"; 182 | break; 183 | case 1: 184 | strOut += rndRegex + ".exec(" + rndOne + ");\n"; 185 | break; 186 | 187 | } 188 | 189 | } 190 | //3. test compile(). compiled items will be reused in galaxyFuzz. 191 | 192 | for(var i = 0; i < g_variant_tank_count_regexy; i++) 193 | { 194 | strOut += "v_regexy_" + i.toString() + " = " + generateOneRegex(true) + ";\n"; 195 | strOut += "v_regexy_" + i.toString() + ".compile();\n"; 196 | } 197 | 198 | /* 199 | todo: do this later. 200 | global 201 | ignoreCase 202 | lastIndex 203 | multiline 204 | source 205 | */ 206 | 207 | stmtPush(strOut); 208 | return strOut; 209 | 210 | } 211 | 212 | function generateSomeAggresiveString() 213 | { 214 | return generateRandomRegexMeta(); 215 | } -------------------------------------------------------------------------------- /classy/classfuzz.js: -------------------------------------------------------------------------------- 1 | 2 | function generateRndClassAttrVarFromTank() 3 | { 4 | return g_tankVariant_attrofobject[parseInt(rand(g_tankVariant_attrofobject.length))]; 5 | } 6 | 7 | function genClassyInitParameter() 8 | { 9 | var rnd = rand(8); 10 | switch (rnd) 11 | { 12 | case 0: 13 | return ''; 14 | case 1: 15 | return 'this'; 16 | case 2: 17 | return 'window'; 18 | case 3: 19 | return 'navigator'; 20 | case 4: 21 | return generateOneMathStatement('', 0, 2); 22 | case 5: 23 | return generateOneRegex(true); 24 | case 6: 25 | return generateOneStringStatement(true); 26 | case 7: 27 | return generateOneArrayStatement(true); 28 | } 29 | 30 | } 31 | 32 | 33 | function generateIfClause(ifWhat, ifTrueThenWhat, elseDoWhat) 34 | { 35 | var out = "if ("; 36 | out += ifWhat + ") {\n\t"; 37 | out += ifTrueThenWhat + "\n}\n"; 38 | if(elseDoWhat.length) 39 | { 40 | out += "else\n{\n\t" 41 | out += elseDoWhat + "\n}\n" 42 | } 43 | return out; 44 | } 45 | 46 | function generateOneJSONStatement() 47 | { 48 | var items = rand(8); 49 | var out = '{'; 50 | 51 | for(var i = 0; i < items; i++) 52 | { 53 | var keyLen = 2 + rand(6); 54 | var key = generateRandomChar(keyLen, false); 55 | var value = genClassyInitParameter(); 56 | if(value == '') value = "\"\""; 57 | 58 | out += "\"" + key + "\"" + ":" + value + ", \n"; 59 | 60 | } 61 | 62 | out += "}"; 63 | return out; 64 | } 65 | 66 | function generateClassFunctionStatements(stmtcount) 67 | { 68 | for(var i = 0; i < stmtcount; i++) 69 | { 70 | var rnd = rand(7); 71 | switch (rnd) 72 | { 73 | case 0: 74 | { 75 | var leftOprand = g_tankVariant_mathy[rand(g_tankVariant_mathy.length)]; 76 | var rndTwoWayOp = getRndTwoWayOp(false); 77 | var rightOprand = rand(2) ? g_tankVariant_mathy[rand(g_tankVariant_mathy.length)] : 78 | generateOneMathStatement('', 0, 2); 79 | if(rightOprand.length < 2) rightOprand = 'this'; 80 | if(rightOprand.indexOf("try{") != 0) 81 | return leftOprand + rndTwoWayOp + rightOprand + ";\n"; 82 | else 83 | return leftOprand + rndTwoWayOp + 'null; \n'; 84 | } 85 | case 1: 86 | { 87 | var leftOprand = g_tankVariant_regexy[rand(g_tankVariant_regexy.length)]; 88 | var assignOp = '='; 89 | var rightOprand = generateOneRegex(true); 90 | if(rightOprand.length < 2) rightOprand = 'this'; 91 | 92 | return leftOprand + assignOp + rightOprand + ";\n" + leftOprand + ".compile();\n"; 93 | } 94 | case 2: 95 | { 96 | var leftOprand = g_tankVariant_arrayy[rand(g_tankVariant_arrayy.length)]; 97 | var assignOp = '='; 98 | var rightOprand = generateOneArrayStatement(true); 99 | 100 | //retry! 101 | if(rightOprand.length < 2) rightOprand = 'this'; 102 | 103 | return leftOprand + assignOp + rightOprand + ";\n" 104 | } 105 | case 3: 106 | { 107 | var ifWhat = getRndItemInGlobalTank() + " instanceof " + getOneOfInstancesInRuntime(); 108 | var thenWhat = getRndItemInGlobalTank() + " = " + generateOneJSONStatement(); 109 | var elseWhat = rand(2) ? '' : getRndItemInGlobalTank() + " = " + generateOneJSONStatement(); 110 | return generateIfClause(ifWhat, thenWhat, elseWhat); 111 | } 112 | case 4: 113 | { 114 | var accessWhat = getRndItemInGlobalTank(); 115 | if(accessWhat == undefined || accessWhat == 'undefined') 116 | accessWhat = "[]" 117 | var accessStmt = generateElementAccess(accessWhat, rand(10)); 118 | var rndTwoWayOp = getRndTwoWayOp(false); 119 | var rightOprand = rand(2) ? g_tankVariant_mathy[rand(g_tankVariant_mathy.length)] : 120 | generateOneMathStatement('', 0, 2); 121 | if(rightOprand.length < 2) rightOprand = 'this'; 122 | if(rightOprand.indexOf("try{") == 0) rightOprand = "null"; 123 | 124 | return '"xy";'+ accessStmt + rndTwoWayOp + rightOprand + ";\n"; 125 | } 126 | case 5: 127 | { 128 | var accessWhat = getRndItemInGlobalTank(); 129 | var accessStmt = generateElementAccess(accessWhat, rand(0xffffffff)); 130 | var rndTwoWayOp = getRndTwoWayOp(false); 131 | var rightOprand = rand(2) ? g_tankVariant_mathy[rand(g_tankVariant_mathy.length)] : 132 | generateOneMathStatement('', 0, 2); 133 | if(rightOprand.length < 2) rightOprand = 'this'; 134 | if(rightOprand.indexOf("try{") == 0) rightOprand = "null"; 135 | 136 | return '"xz";'+ accessStmt + rndTwoWayOp + rightOprand + ";\n"; 137 | } 138 | case 6: 139 | { 140 | var windowStmt = g_funcList_windowy_returnString[rand(g_funcList_windowy_returnString.length)]; 141 | return windowStmt[windowStmt.length - 2].replace("[1]" , generateOneStringStatement(true)); 142 | 143 | } 144 | } 145 | } 146 | } 147 | 148 | 149 | function generateClassAssignmentStmt() 150 | { 151 | var attr1 = generateRndClassAttrVarFromTank(); 152 | var attr2 = generateRndClassAttrVarFromTank(); 153 | var item1 = g_tankVariant_classyv[rand(g_tankVariant_classyv.length)]; 154 | var item2 = g_tankVariant_classyv[rand(g_tankVariant_classyv.length)]; 155 | var op1 = getRndTwoWayOp(false); 156 | var op2 = getRndTwoWayOp(false); 157 | var out = item1 + "." + attr1 + " " + op1 + " (" + generateClassFunctionStatements(1 + rand(5)) + "); \r\n" + 158 | item2 + "." + attr2 + " " + op2 + " (" + generateClassFunctionStatements(1 + rand(5)) + "); \r\n"; 159 | 160 | for(var x = 0; x < 1; x++) 161 | { 162 | var assignmentTotal = 1 + rand(2); 163 | out += "Object.assign(" + (x == 0 ? item1 : item2); 164 | for(let i = 0; i < assignmentTotal; i++) 165 | { 166 | if(i != assignmentTotal) 167 | out += ","; 168 | if(rand(2)) 169 | out += (x == 0 ? item2 : item1); 170 | else 171 | out += getRndItemInGlobalTank(); 172 | } 173 | out += ");\r\n"; 174 | } 175 | 176 | return out; 177 | } 178 | 179 | function generateOneClassFuzzStatement() 180 | { 181 | var out = ''; 182 | 183 | var item = g_tankVariant_classyv[rand(g_tankVariant_classyv.length)]; 184 | var op = getRndTwoWayOp(false); 185 | out += item + ".fuzz(); \n"; 186 | out += item + op + g_NScript_builtin_prototypes[rand(g_NScript_builtin_prototypes.length)] + "; 'warning';\n"; 187 | 188 | return out; 189 | } 190 | 191 | function classFuzz() 192 | { 193 | for(var i = 0; i < 10; i++) 194 | stmtPush(generateOneClassFuzzStatement()); 195 | } 196 | -------------------------------------------------------------------------------- /stringy/stringfuzz.js: -------------------------------------------------------------------------------- 1 | 2 | function generateRandomChar(length, pureString) { 3 | var str = ''; 4 | for ( ; str.length < length;) 5 | { 6 | switch(rand(4)) 7 | { 8 | case 0: //25% chance 9 | if(!pureString) 10 | { 11 | //str += generateRandomRegexMeta(); 12 | str+="\\x41"; 13 | break; 14 | } 15 | case 1: 16 | case 2: 17 | case 3: 18 | str += Math.random().toString(36).substr(3,1); 19 | break; 20 | } 21 | } 22 | return str; 23 | } 24 | 25 | function generateOneRndUnicodeOrNormal() 26 | { 27 | //return ('0x' + getRandomInt(0, 9999).toString()); 28 | return String.fromCharCode(rand(0xffff)); 29 | } 30 | 31 | 32 | var g_ruleList_string_Operations = new Array( 33 | 34 | [STRING, 2, STRING, CAN_BE_INSTANT_VAL, NUMBER, CAN_BE_INSTANT_VAL, "[1].charAt([2])", FRAGMENT], 35 | [STRING, 2, STRING, CAN_BE_INSTANT_VAL, STRING, CAN_BE_INSTANT_VAL, "[1].concat([2])", FRAGMENT], 36 | [STRING, 1, COMMA_MULTILIST, CAN_BE_INSTANT_VAL, "String.fromCharCode([1])", FRAGMENT], 37 | [NUMBER, 2, STRING, CAN_BE_INSTANT_VAL, STRING, CAN_BE_INSTANT_VAL, "[1].indexOf([2])", FRAGMENT], 38 | [STRING, 2, STRING, CAN_BE_INSTANT_VAL, STRING, CAN_BE_INSTANT_VAL, "[1].lastIndexOf([2])", FRAGMENT], 39 | [STRING, 2, STRING, CAN_BE_INSTANT_VAL, STRING, CAN_BE_INSTANT_VAL,"[1].localeCompare([2])", FRAGMENT], 40 | [STRING, 2, STRING, CAN_BE_INSTANT_VAL, REGEX, CAN_BE_INSTANT_VAL,"[1].match([2])", FRAGMENT], 41 | [STRING, 3, STRING, CAN_BE_INSTANT_VAL, REGEX, CAN_BE_INSTANT_VAL, STRING, CAN_BE_INSTANT_VAL, "[1].replace([2], [3])", FRAGMENT], 42 | [STRING, 2, STRING, CAN_BE_INSTANT_VAL, REGEX, CAN_BE_INSTANT_VAL,"[1].search([2])", FRAGMENT], 43 | [STRING, 3, STRING, CAN_BE_INSTANT_VAL, NUMBER, CAN_BE_INSTANT_VAL, NUMBER, CAN_BE_INSTANT_VAL, "[1].slice([2], [3])", FRAGMENT], 44 | [STRING, 3, STRING, CAN_BE_INSTANT_VAL, REGEX, CAN_BE_INSTANT_VAL, NUMBER, CAN_BE_INSTANT_VAL, "[1].split([2], [3])", FRAGMENT], 45 | [STRING, 3, STRING, CAN_BE_INSTANT_VAL, STRING, CAN_BE_INSTANT_VAL, NUMBER, CAN_BE_INSTANT_VAL, "[1].split([2], [3])", FRAGMENT], 46 | [STRING, 3, STRING, CAN_BE_INSTANT_VAL, NUMBER, CAN_BE_INSTANT_VAL, NUMBER, CAN_BE_INSTANT_VAL, "[1].substr([2], [3])", FRAGMENT], 47 | [STRING, 3, STRING, CAN_BE_INSTANT_VAL, NUMBER, CAN_BE_INSTANT_VAL, NUMBER, CAN_BE_INSTANT_VAL, "[1].substring([2], [3])", FRAGMENT], 48 | [STRING, 1, STRING, CAN_BE_INSTANT_VAL, "[1].toLocaleLowerCase()", FRAGMENT], 49 | [STRING, 1, STRING, CAN_BE_INSTANT_VAL, "[1].toLocaleUpperCase()", FRAGMENT], 50 | [STRING, 1, STRING, CAN_BE_INSTANT_VAL, "[1].toLowerCase()", FRAGMENT], 51 | [STRING, 1, STRING, CAN_BE_INSTANT_VAL, "[1].toUpperCase()", FRAGMENT], 52 | [STRING, 1, STRING, CAN_BE_INSTANT_VAL, "[1].toString()", FRAGMENT], 53 | [STRING, 1, STRING, CAN_BE_INSTANT_VAL, "[1].valueOf()", FRAGMENT] 54 | ); 55 | 56 | 57 | function generateOneString() 58 | { 59 | var out = ''; 60 | var len = 1 +rand(14); 61 | for(var i = 0; i < len; i++) 62 | { 63 | switch(rand(2)) 64 | { 65 | case 0: 66 | out += generateRandomChar(5, false); 67 | break; 68 | case 1: 69 | out += generateOneRndUnicodeOrNormal(); 70 | break; 71 | } 72 | } 73 | out = out.replace(/\r/g,"x") 74 | out = out.replace(/\n/g,"x") 75 | out = out.replace(/"/g,"x") 76 | out = out.replace(/\u2028/g,"x") 77 | out = out.replace(/\u2029/g,"x") 78 | return out; 79 | 80 | } 81 | 82 | function generateRndStringVarFromTank() 83 | { 84 | return g_tankVariant_stringy[parseInt(rand(g_tankVariant_stringy.length))]; 85 | } 86 | 87 | // you can specific to replace [1] or something with specific 88 | // statement so you can fuzz like a chain-statement 89 | // EG: replace all STRING with specific "XXX" will generate: 90 | // 1time : "XXX".toLowerCase() -->Statement1 91 | // 2times: Statement1.toString() -->Statement2 92 | // 3times: Statement2.split('X', 4958); 93 | // 94 | // output: "XXX".toLowerCase().toString().split('X', 4958); 95 | // 96 | 97 | function parseOneFragRuleStringyWithStatement(rule, fragment, replaceWhom) 98 | { 99 | var pos = 0; 100 | var maximumArgCount = rule[1]; 101 | var tempTank = new Array(); 102 | var tankCount = 0; 103 | 104 | //rule[0] : return type 105 | //rule[1] : frag count 106 | //rule[2] : frag descriptor 107 | 108 | for(var i = 0, j = 0; i < maximumArgCount; i += 1, j += 2) 109 | { 110 | if(rule[2 + j] == STRING && rule[2 + j + 1] == CAN_BE_INSTANT_VAL) 111 | { 112 | var choose = rand(2); 113 | switch(choose) 114 | { 115 | case 0: 116 | //from global string tank; 117 | tempTank[tankCount++] = generateRndStringVarFromTank(); 118 | break; 119 | case 1: 120 | tempTank[tankCount++] = "\"" + generateOneString() + "\""; 121 | break; 122 | 123 | //todo: from global runtime tank; 124 | } 125 | } 126 | else if(rule[2 + j] == REGEX && rule[2 + j + 1] == CAN_BE_INSTANT_VAL) 127 | { 128 | var choose = rand(2); 129 | switch(choose) 130 | { 131 | case 0: 132 | //from global regex tank; 133 | tempTank[tankCount++] = generateRndRegexVarFromTank(); 134 | break; 135 | case 1: 136 | tempTank[tankCount++] = generateOneRegex(true) ; 137 | break; 138 | 139 | //todo: from global runtime tank; 140 | } 141 | } 142 | else if(rule[2 + j] == NUMBER && rule[2 + j + 1] == CANT_BE_INSTANT_VAL) 143 | tempTank[tankCount++] = generateRndVarFromTank(); 144 | else if(rule[2 + j] == NUMBER && rule[2 + j + 1] == CAN_BE_INSTANT_VAL) 145 | tempTank[tankCount++] = generateRndNumber(); 146 | else if(rule[2 + j] == GENERAL_OBJECT && rule[2 + j + 1] == CANT_BE_INSTANT_VAL) 147 | tempTank[tankCount++] = generateRndVarFromTank(); 148 | else if(rule[2 + j] == GENERAL_OBJECT && rule[2 + j + 1] == CAN_BE_INSTANT_VAL) 149 | tempTank[tankCount++] = generateRndNumber(); 150 | else if(rule[2 + j] == COMMA_MULTILIST) 151 | tempTank[tankCount++] = generateOneMathStatement('', 0, 2); 152 | 153 | } 154 | 155 | var fragmentFormat = rule[j + 2]; 156 | for(var i = 1; i <= maximumArgCount; i++) 157 | { 158 | if(replaceWhom == i) 159 | fragmentFormat = fragmentFormat.replace('[' + replaceWhom.toString() + ']', fragment); 160 | else 161 | fragmentFormat = fragmentFormat.replace('[' + i.toString() + ']', tempTank[i - 1]); 162 | } 163 | 164 | return fragmentFormat; 165 | } 166 | 167 | 168 | //parse one rule and generate one fragment. 169 | function parseOneFragRuleStringy(rule) 170 | { 171 | var pos = 0; 172 | var maximumArgCount = rule[1]; 173 | var tempTank = new Array(); 174 | var tankCount = 0; 175 | 176 | //rule[0] : return type 177 | //rule[1] : frag count 178 | //rule[2] : frag descriptor 179 | 180 | for(var i = 0, j = 0; i < maximumArgCount; i += 1, j += 2) 181 | { 182 | if(rule[2 + j] == STRING && rule[2 + j + 1] == CAN_BE_INSTANT_VAL) 183 | { 184 | var choose = rand(2); 185 | switch(choose) 186 | { 187 | case 0: 188 | //from global string tank; 189 | tempTank[tankCount++] = generateRndStringVarFromTank(); 190 | break; 191 | case 1: 192 | tempTank[tankCount++] = "\"" + generateOneString() + "\""; 193 | break; 194 | 195 | //todo: from global runtime tank; 196 | } 197 | } 198 | else if(rule[2 + j] == REGEX && rule[2 + j + 1] == CAN_BE_INSTANT_VAL) 199 | { 200 | var choose = rand(2); 201 | switch(choose) 202 | { 203 | case 0: 204 | //from global regex tank; 205 | tempTank[tankCount++] = generateRndRegexVarFromTank(); 206 | break; 207 | case 1: 208 | tempTank[tankCount++] = generateOneRegex(true) ; 209 | break; 210 | 211 | //todo: from global runtime tank; 212 | } 213 | } 214 | else if(rule[2 + j] == NUMBER && rule[2 + j + 1] == CANT_BE_INSTANT_VAL) 215 | tempTank[tankCount++] = generateRndVarFromTank(); 216 | else if(rule[2 + j] == NUMBER && rule[2 + j + 1] == CAN_BE_INSTANT_VAL) 217 | tempTank[tankCount++] = generateRndNumber(); 218 | else if(rule[2 + j] == GENERAL_OBJECT && rule[2 + j + 1] == CANT_BE_INSTANT_VAL) 219 | tempTank[tankCount++] = generateRndVarFromTank(); 220 | else if(rule[2 + j] == GENERAL_OBJECT && rule[2 + j + 1] == CAN_BE_INSTANT_VAL) 221 | tempTank[tankCount++] = generateRndNumber(); 222 | else if(rule[2 + j] == COMMA_MULTILIST) 223 | tempTank[tankCount++] = generateOneMathStatement('', 0, 2); 224 | 225 | } 226 | 227 | var fragmentFormat = rule[j + 2]; 228 | for(var i = 1; i <= maximumArgCount; i++) 229 | { 230 | fragmentFormat = fragmentFormat.replace('[' + i.toString() + ']', tempTank[i - 1]); 231 | } 232 | 233 | return fragmentFormat; 234 | } 235 | 236 | function generateOneStringStatement(bExactOneStatement) 237 | { 238 | var out = ''; 239 | var genTimes = 2 + rand(4); 240 | 241 | var bStartWithLastStatement = false; 242 | var sLastStatement = ''; 243 | 244 | for(var i = 0; i < genTimes; i++) 245 | { 246 | var tmpRule = g_ruleList_string_Operations[rand(g_ruleList_string_Operations.length)]; 247 | 248 | var retType = tmpRule[0]; 249 | 250 | var tmpFragment; 251 | 252 | if(bStartWithLastStatement) 253 | { 254 | //usually, replace the first one is the safest way to do this.. 255 | //you can idenfify this by type and write a more robust code. It all depends on you. 256 | tmpFragment = parseOneFragRuleStringyWithStatement(tmpRule, sLastStatement, 1); 257 | } 258 | else 259 | { 260 | tmpFragment = parseOneFragRuleStringy(tmpRule); 261 | } 262 | 263 | 264 | if(rand(2) && retType == STRING && i != genTimes) 265 | { 266 | //generate chain statement! 267 | bStartWithLastStatement = true; 268 | sLastStatement = tmpFragment; 269 | } 270 | else 271 | { 272 | bStartWithLastStatement = false; 273 | if(bExactOneStatement) 274 | { 275 | out += tmpFragment; 276 | break; 277 | } 278 | else 279 | out += tmpFragment + ';\n'; 280 | } 281 | } 282 | return out; 283 | } 284 | 285 | 286 | 287 | function stringFuzz() 288 | { 289 | for(var i=0; i < 10; i++) 290 | stmtPush(generateOneStringStatement(false)); 291 | } 292 | -------------------------------------------------------------------------------- /arrayy/arrayfuzz.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | var g_ruleList_array_Operations = new Array( 4 | //retvalue, argcount, argtype, argdecl., func decl., fragment type 5 | [ARRAY, 2, ARRAY, CAN_BE_INSTANT_VAL, COMMA_MULTILIST, CAN_BE_INSTANT_VAL, "[1].concat([2])", FRAGMENT], 6 | [STRING, 2, ARRAY, CAN_BE_INSTANT_VAL, STRING, CAN_BE_INSTANT_VAL, "[1].join([2])", FRAGMENT], 7 | [STRING, 1, ARRAY, CAN_BE_INSTANT_VAL, "[1].join()", FRAGMENT], 8 | [UNDEFINED, 1, ARRAY, CANT_BE_INSTANT_VAL, "[1].pop()", STATEMENT], 9 | [NUMBER, 2, ARRAY, CANT_BE_INSTANT_VAL, COMMA_MULTILIST, CAN_BE_INSTANT_VAL, "[1].push([2])", STATEMENT], 10 | [ARRAY, 1, ARRAY, CAN_BE_INSTANT_VAL, "[1].reverse()", FRAGMENT], 11 | [OBJECT, 1, ARRAY, CANT_BE_INSTANT_VAL, "[1].shift()", FRAGMENT], 12 | [ARRAY, 2, ARRAY, CANT_BE_INSTANT_VAL, NUMBER, CAN_BE_INSTANT_VAL, "[1].slice([2])", FRAGMENT], 13 | [ARRAY, 3, ARRAY, CANT_BE_INSTANT_VAL, NUMBER, CAN_BE_INSTANT_VAL, NUMBER, CAN_BE_INSTANT_VAL, "[1].slice([2], [3])", FRAGMENT], 14 | [ARRAY, 1, ARRAY, CAN_BE_INSTANT_VAL, "[1].sort()", FRAGMENT], 15 | [ARRAY, 2, ARRAY, CAN_BE_INSTANT_VAL, FUNCTION, CAN_BE_INSTANT_VAL, "[1].sort([2])", FRAGMENT], 16 | [ARRAY, 3, ARRAY, CAN_BE_INSTANT_VAL, NUMBER, CAN_BE_INSTANT_VAL, NUMBER, CAN_BE_INSTANT_VAL, "[1].splice([2], [3])", FRAGMENT], 17 | [ARRAY, 4, ARRAY, CAN_BE_INSTANT_VAL, NUMBER, CAN_BE_INSTANT_VAL, NUMBER, CAN_BE_INSTANT_VAL, COMMA_MULTILIST, CAN_BE_INSTANT_VAL, "[1].splice([2], [3], [4])", FRAGMENT], 18 | [NUMBER, 2, ARRAY, CANT_BE_INSTANT_VAL, COMMA_MULTILIST, CAN_BE_INSTANT_VAL, "[1].unshift([2])", STATEMENT], 19 | [STRING, 1, ARRAY, CAN_BE_INSTANT_VAL, "[1].toString()", FRAGMENT], 20 | [STRING, 1, ARRAY, CAN_BE_INSTANT_VAL, "[1].toLocaleString()", FRAGMENT], 21 | [NUMBER, 1, ARRAY, CAN_BE_INSTANT_VAL, "[1].isArray()", FRAGMENT], 22 | //[ARRAY, 2, ARRAY, CAN_BE_INSTANT_VAL, NUMBER, CAN_BE_INSTANT_VAL, "[1].fill([2])", FRAGMENT], 23 | [NUMBER, 2, ARRAY, CAN_BE_INSTANT_VAL, NUMBER, CAN_BE_INSTANT_VAL, "[1].indexOf([2])", FRAGMENT], 24 | [NUMBER, 2, ARRAY, CAN_BE_INSTANT_VAL, NUMBER, CAN_BE_INSTANT_VAL, "[1].lastIndexOf([2])", FRAGMENT], 25 | //[ARRAY, 2, ARRAY, CAN_BE_INSTANT_VAL, STRING, CAN_BE_INSTANT_VAL, "[1].fill([2])", FRAGMENT], 26 | [NUMBER, 2, ARRAY, CAN_BE_INSTANT_VAL, STRING, CAN_BE_INSTANT_VAL, "[1].indexOf([2])", FRAGMENT], 27 | [NUMBER, 2, ARRAY, CAN_BE_INSTANT_VAL, NUMBER, CAN_BE_INSTANT_VAL, "[1].indexOf([2])", FRAGMENT], 28 | [NUMBER, 3, ARRAY, CAN_BE_INSTANT_VAL, NUMBER, CAN_BE_INSTANT_VAL, ARRAY, CAN_BE_INSTANT_VAL, "[1].indexOf([2], [3])", FRAGMENT], 29 | [NUMBER, 4, ARRAY, CAN_BE_INSTANT_VAL, NUMBER, CAN_BE_INSTANT_VAL, STRING, CAN_BE_INSTANT_VAL, FUNCTION, CAN_BE_INSTANT_VAL, "[1].indexOf([2], {[3]:[4]})", FRAGMENT], 30 | [NUMBER, 2, ARRAY, CAN_BE_INSTANT_VAL, STRING, CAN_BE_INSTANT_VAL, "[1].lastIndexOf([2])", FRAGMENT] 31 | 32 | ); 33 | 34 | 35 | // you can specific to replace [1] or something with specific 36 | // statement so you can fuzz like a chain-statement 37 | // EG: replace all STRING with specific "XXX" will generate: 38 | // 1time : "XXX".toLowerCase() -->Statement1 39 | // 2times: Statement1.toString() -->Statement2 40 | // 3times: Statement2.split('X', 4958); 41 | // 42 | // output: "XXX".toLowerCase().toString().split('X', 4958); 43 | // 44 | 45 | function parseOneFragRuleArrayyWithStatement(rule, fragment, replaceWhom) 46 | { 47 | var pos = 0; 48 | var maximumArgCount = rule[1]; 49 | var tempTank = new Array(); 50 | var tankCount = 0; 51 | 52 | //rule[0] : return type 53 | //rule[1] : frag count 54 | //rule[2] : frag descriptor 55 | 56 | for(var i = 0, j = 0; i < maximumArgCount; i += 1, j += 2) 57 | { 58 | if(rule[2 + j] == ARRAY && rule[2 + j + 1] == CAN_BE_INSTANT_VAL) 59 | { 60 | var choose = rand(2); 61 | switch(choose) 62 | { 63 | case 0: 64 | //from global string tank; 65 | tempTank[tankCount++] = generateRndArrayVarFromTank(); 66 | break; 67 | case 1: 68 | tempTank[tankCount++] = "[" + generateOneArrayInitTable() + "]"; 69 | break; 70 | 71 | //todo: from global runtime tank; 72 | } 73 | } 74 | else if(rule[2 + j] == ARRAY && rule[2 + j + 1] == CANT_BE_INSTANT_VAL) 75 | { 76 | tempTank[tankCount++] = generateRndArrayVarFromTank(); 77 | } 78 | else if(rule[2 + j] == STRING && rule[2 + j + 1] == CAN_BE_INSTANT_VAL) 79 | { 80 | var choose = rand(2); 81 | switch(choose) 82 | { 83 | case 0: 84 | //from global string tank; 85 | tempTank[tankCount++] = generateRndStringVarFromTank(); 86 | break; 87 | case 1: 88 | tempTank[tankCount++] = "\"" + generateOneString() + "\""; 89 | break; 90 | 91 | //todo: from global runtime tank; 92 | } 93 | } 94 | else if(rule[2 + j] == REGEX && rule[2 + j + 1] == CAN_BE_INSTANT_VAL) 95 | { 96 | var choose = rand(2); 97 | switch(choose) 98 | { 99 | case 0: 100 | //from global regex tank; 101 | tempTank[tankCount++] = generateRndRegexVarFromTank(); 102 | break; 103 | case 1: 104 | tempTank[tankCount++] = generateOneRegex(true) ; 105 | break; 106 | 107 | //todo: from global runtime tank; 108 | } 109 | } 110 | else if(rule[2 + j] == NUMBER && rule[2 + j + 1] == CANT_BE_INSTANT_VAL) 111 | tempTank[tankCount++] = generateRndVarFromTank(); 112 | else if(rule[2 + j] == NUMBER && rule[2 + j + 1] == CAN_BE_INSTANT_VAL) 113 | tempTank[tankCount++] = generateRndNumber(); 114 | else if(rule[2 + j] == GENERAL_OBJECT && rule[2 + j + 1] == CANT_BE_INSTANT_VAL) 115 | tempTank[tankCount++] = generateRndVarFromTank(); 116 | else if(rule[2 + j] == GENERAL_OBJECT && rule[2 + j + 1] == CAN_BE_INSTANT_VAL) 117 | tempTank[tankCount++] = generateRndNumber(); 118 | else if(rule[2 + j] == COMMA_MULTILIST) //todo: does this need to change to meet our need?? 119 | tempTank[tankCount++] = generateOneMathStatement('', 0, 2); 120 | 121 | } 122 | 123 | var fragmentFormat = rule[j + 2]; 124 | for(var i = 1; i <= maximumArgCount; i++) 125 | { 126 | if(replaceWhom == i) 127 | fragmentFormat = fragmentFormat.replace('[' + replaceWhom.toString() + ']', fragment); 128 | else 129 | fragmentFormat = fragmentFormat.replace('[' + i.toString() + ']', tempTank[i - 1]); 130 | } 131 | 132 | return fragmentFormat; 133 | } 134 | 135 | function generateRndArrayVarFromTank() 136 | { 137 | return g_tankVariant_arrayy[parseInt(rand(g_tankVariant_arrayy.length))]; 138 | } 139 | 140 | //parse one rule and generate one fragment. 141 | function parseOneFragRuleArrayy(rule) 142 | { 143 | var pos = 0; 144 | var maximumArgCount = rule[1]; 145 | var tempTank = new Array(); 146 | var tankCount = 0; 147 | 148 | //rule[0] : return type 149 | //rule[1] : frag count 150 | //rule[2] : frag descriptor 151 | 152 | for(var i = 0, j = 0; i < maximumArgCount; i += 1, j += 2) 153 | { 154 | if(rule[2 + j] == ARRAY && rule[2 + j + 1] == CAN_BE_INSTANT_VAL) 155 | { 156 | var choose = rand(2); 157 | switch(choose) 158 | { 159 | case 0: 160 | //from global string tank; 161 | tempTank[tankCount++] = generateRndArrayVarFromTank(); 162 | break; 163 | case 1: 164 | tempTank[tankCount++] = "[" + generateOneArrayInitTable() + "]"; 165 | break; 166 | 167 | //todo: from global runtime tank; 168 | } 169 | } 170 | else if(rule[2 + j] == ARRAY && rule[2 + j + 1] == CANT_BE_INSTANT_VAL) 171 | { 172 | tempTank[tankCount++] = generateRndArrayVarFromTank(); 173 | } 174 | else if(rule[2 + j] == STRING && rule[2 + j + 1] == CAN_BE_INSTANT_VAL) 175 | { 176 | var choose = rand(2); 177 | switch(choose) 178 | { 179 | case 0: 180 | //from global string tank; 181 | tempTank[tankCount++] = generateRndStringVarFromTank(); 182 | break; 183 | case 1: 184 | tempTank[tankCount++] = "\"" + generateOneString() + "\""; 185 | break; 186 | 187 | //todo: from global runtime tank; 188 | } 189 | } 190 | else if(rule[2 + j] == REGEX && rule[2 + j + 1] == CAN_BE_INSTANT_VAL) 191 | { 192 | var choose = rand(2); 193 | switch(choose) 194 | { 195 | case 0: 196 | //from global regex tank; 197 | tempTank[tankCount++] = generateRndRegexVarFromTank(); 198 | break; 199 | case 1: 200 | tempTank[tankCount++] = generateOneRegex(true) ; 201 | break; 202 | 203 | //todo: from global runtime tank; 204 | } 205 | } 206 | else if(rule[2 + j] == NUMBER && rule[2 + j + 1] == CANT_BE_INSTANT_VAL) 207 | tempTank[tankCount++] = generateRndVarFromTank(); 208 | else if(rule[2 + j] == NUMBER && rule[2 + j + 1] == CAN_BE_INSTANT_VAL) 209 | tempTank[tankCount++] = generateRndNumber(); 210 | else if(rule[2 + j] == GENERAL_OBJECT && rule[2 + j + 1] == CANT_BE_INSTANT_VAL) 211 | tempTank[tankCount++] = generateRndVarFromTank(); 212 | else if(rule[2 + j] == GENERAL_OBJECT && rule[2 + j + 1] == CAN_BE_INSTANT_VAL) 213 | tempTank[tankCount++] = generateRndNumber(); 214 | else if(rule[2 + j] == COMMA_MULTILIST) //todo: does this need to change to meet our need?? 215 | tempTank[tankCount++] = generateOneMathStatement('', 0, 2); 216 | 217 | } 218 | 219 | var fragmentFormat = rule[j + 2]; 220 | for(var i = 1; i <= maximumArgCount; i++) 221 | { 222 | fragmentFormat = fragmentFormat.replace('[' + i.toString() + ']', tempTank[i - 1]); 223 | } 224 | 225 | return fragmentFormat; 226 | } 227 | 228 | 229 | function generateOneArrayStatement(bExactOneStatement) 230 | { 231 | var out = ''; 232 | var genTimes = 2 + rand(4); 233 | 234 | var bStartWithLastStatement = false; 235 | var sLastStatement = ''; 236 | 237 | for(var i = 0; i < genTimes; i++) 238 | { 239 | var tmpRule = g_ruleList_array_Operations[rand(g_ruleList_array_Operations.length)]; 240 | 241 | var retType = tmpRule[0]; 242 | 243 | var tmpFragment; 244 | 245 | if(bStartWithLastStatement) 246 | { 247 | //usually, replace the first one is the safest way to do this.. 248 | //you can idenfify this by type and write a more robust code. It all depends on you. 249 | tmpFragment = parseOneFragRuleArrayyWithStatement(tmpRule, sLastStatement, 1); 250 | } 251 | else 252 | { 253 | tmpFragment = parseOneFragRuleArrayy(tmpRule); 254 | } 255 | 256 | 257 | if(rand(2) && retType == ARRAY && i != genTimes) 258 | { 259 | //generate chain statement! 260 | bStartWithLastStatement = true; 261 | sLastStatement = tmpFragment; 262 | } 263 | else 264 | { 265 | bStartWithLastStatement = false; 266 | if(bExactOneStatement) 267 | { 268 | out += tmpFragment; 269 | break; 270 | } 271 | else 272 | out += tmpFragment + ';\n'; 273 | } 274 | } 275 | return out; 276 | } 277 | 278 | 279 | function arrayFuzz() 280 | { 281 | for(var i = 0; i < 10; i++) 282 | stmtPush(generateOneArrayStatement(false)); 283 | } 284 | -------------------------------------------------------------------------------- /lucky-jsfuzz-chrome.html: -------------------------------------------------------------------------------- 1 | 2 |