MVP setup and (sort of) working

Took 1 hour 58 minutes
This commit is contained in:
ayrton 2023-11-18 20:13:15 -07:00
parent f911c05e3d
commit ac146b4595
18 changed files with 378 additions and 117 deletions

View file

@ -10,18 +10,19 @@ This is a hecking fuzzer. It does the thing.
## Usage
```
usage: python -m gazprea_fuzzer.py [-h] [-b SIZE] [--seed SEED] <config_file>
usage: gazprea_fuzzer.py [-h] [-b BATCH] [--seed SEED] config_file
Procedurally generate a test case for Gazprea
positional arguments:
config path to your configuration file
name name of the test case to generate (name.in, name.ins, name.out)
optional arguments:
-h, --help show the help message and exit
-b, --batch SIZE generate SIZE cases (fuzzer/input/nameX.in, /instream/..., /outputs/...)
--seed SEED rng seed
config_file path to your configuration file
options:
-h, --help show this help message and exit
-b BATCH, --batch BATCH
generate SIZE cases (fuzzer/input/nameX.in,
/instream/..., /outputs/...)
--seed SEED rng seed
```
## Configuration

View file

@ -124,7 +124,7 @@ class AstGenerator:
self.current_ast_element.append(xml_element)
parent = self.current_ast_element
self.current_ast_element = xml_element
self.current_ast_element.append(self.make_literal(return_value, return_type))
self.current_ast_element.append(self.make_literal(return_type, return_value))
self.current_ast_element = parent
return
@ -166,8 +166,8 @@ class AstGenerator:
def generate_statements(self):
# Number line
number_line = 100
cutoffs = [10, 30, 50, 80, 100]
number_line = 180 #TODO fix the numberline stuff to reflect the settings
cutoffs = [10, 30, 50, 80, 100, 140, 180]
options = {
0: self.generate_declaration,
1: self.generate_routine_call,

View file

@ -1,5 +1,6 @@
import os
import shutil
import warnings
import xml.etree.ElementTree as ET
from ast_parser.general_unparser import GeneralUnparser
@ -21,6 +22,47 @@ def to_gazprea_type(ty: str): #TODO implement the compound types
raise Exception("Unknown type: " + ty)
def _unparse_arg(node):
return "{} {}".format(to_gazprea_type(node.get(GAZ_TY_KEY)), node.get(GAZ_NAME_KEY))
def to_gaz_value(val):
if val in ["True", "False"]:
return val.lower()
else:
return str(val)
def to_gaz_op(param):
if param == "negation" or param == "subtraction":
return "-"
elif param == "addition":
return "+"
elif param == "multiplication":
return "*"
elif param == "division":
return "/"
elif param == "modulus":
return "%"
elif param == "power":
return "^"
elif param == "equality":
return "=="
elif param == "inequality":
return "!="
elif param == "less-than":
return "<"
elif param == "less-than-or-equal":
return "<="
elif param == "greater-than":
return ">"
elif param == "greater-than-or-equal":
return ">="
else:
warnings.warn("Warning, unknown operator: " + param)
return param
class AstParser(GeneralUnparser):
def __init__(self, input: str or ET.Element, from_xml: bool = False):
if from_xml:
@ -54,6 +96,8 @@ class AstParser(GeneralUnparser):
self.unparse_return(node)
elif node.tag == GAZ_OPERATOR_TAG:
self.unparse_operator(node)
elif node.tag == GAZ_UNARY_OPERATOR_TAG:
self.unparse_unary(node)
elif node.tag == GAZ_STREAM_TAG:
self.unparse_stream(node)
elif node.tag == GAZ_LIT_TAG:
@ -66,6 +110,12 @@ class AstParser(GeneralUnparser):
self._xhs_unparse(node)
elif node.tag == GAZ_LIT_TAG:
self.unparse_literal(node)
elif node.tag == GAZ_ASSIGNMENT_TAG:
self.unparse_assignment(node)
elif node.tag == GAZ_IF_TAG:
self.unparse_conditional(node)
elif node.tag == GAZ_LOOP_TAG:
self.unparse_loop(node)
else:
raise Exception("Unknown tag: " + node.tag)
@ -75,7 +125,10 @@ class AstParser(GeneralUnparser):
for child in node:
self.unparse_node(child)
self.indentation -= 4
self.input += "}\n\n"
if node.get(GAZ_TY_KEY) is None:
self.input += "}\n\n"
elif node.get(GAZ_TY_KEY) in [GAZ_TRUE_BLOCK_TAG, GAZ_FALSE_BLOCK_TAG]:
self.input += "}"
def unparse_declaration(self, node):
variable = node.find(GAZ_VAR_TAG)
@ -96,9 +149,9 @@ class AstParser(GeneralUnparser):
self.input += "{}".format(node.get(GAZ_NAME_KEY))
def unparse_stream(self, node):
if node.tag == GAZ_OUT_STREAM:
if node.get(GAZ_TY_KEY) == GAZ_OUT_STREAM:
self.unparse_outstream(node)
elif node.tag == GAZ_IN_STREAM:
elif node.get(GAZ_TY_KEY) == GAZ_IN_STREAM:
self.unparse_instream(node)
def unparse_instream(self, node):
@ -111,10 +164,10 @@ class AstParser(GeneralUnparser):
for child in node:
self.unparse_node(child)
self.input += "-> {};\n".format(GAZ_OUT_STREAM)
self.input += " -> {};\n".format(GAZ_OUT_STREAM)
def unparse_literal(self, node):
self.input += "{}".format(node.get(GAZ_VAL_KEY))
self.input += "{}".format(to_gaz_value(node.get(GAZ_VAL_KEY)))
def _xhs_unparse(self, node):
for child in node:
@ -122,7 +175,7 @@ class AstParser(GeneralUnparser):
def unparse_operator(self, node):
self._xhs_unparse(node.find(GAZ_LHS_TAG))
self.input += " {} ".format(node.get("op"))
self.input += " {} ".format(to_gaz_op(node.get("op")))
self._xhs_unparse(node.find(GAZ_RHS_TAG))
def unparse_return(self, node):
@ -136,7 +189,12 @@ class AstParser(GeneralUnparser):
if node.get(GAZ_RETURN_KEY) not in [None, GAZ_VOID_TYPE, ""]:
return_type = "returns " + to_gazprea_type(node.get(GAZ_RETURN_KEY))
args = self.unparse_argument(node.findall(GAZ_ARG_TAG))
args = []
for child in node:
if child.tag == GAZ_ARG_TAG:
args.append(child)
args = self.unparse_argument(args)
self.input += "{} {}{} {} ".format(
node.tag,
@ -146,6 +204,8 @@ class AstParser(GeneralUnparser):
)
for child in node:
if child.tag == GAZ_ARG_TAG:
continue
self.unparse_node(child)
# cls.input += "}\n\n" #blocks are already there
@ -155,12 +215,62 @@ class AstParser(GeneralUnparser):
return "()"
args = "("
for i in range(len(nodes)):
args += self._unparse_arg(nodes[i])
args += _unparse_arg(nodes[i])
if i < len(nodes) - 1:
args += ", "
args += ")"
return args
def _unparse_arg(self, node):
return "{} {}".format(to_gazprea_type(node.get(GAZ_TY_KEY)), node.get(GAZ_NAME_KEY))
def unparse_assignment(self, element_in: ET.Element):
self.unparse_variable(element_in.find(GAZ_VAR_TAG), False)
self.input += " = "
self.unparse_node(element_in.find(GAZ_RHS_TAG))
self.input += ";\n"
def unparse_conditional(self, element_in: ET.Element):
self.input += "if ("
i = 0
for node in element_in:
if node.tag == GAZ_IF_TAG:
self.input += " else "
self.unparse_conditional(node)
elif node.tag != GAZ_BLOCK_TAG:
self.unparse_node(node)
self.input += ") "
elif node.tag == GAZ_BLOCK_TAG:
if node.get(GAZ_TY_KEY) == GAZ_TRUE_BLOCK_TAG:
self.unparse_node(node)
elif node.get(GAZ_TY_KEY) == GAZ_FALSE_BLOCK_TAG:
self.input += " else "
self.unparse_node(node)
else:
self.unparse_node(node)
i += 1
def unparse_loop(self, element_in: ET.Element):
self.input += "loop ("
i = 0
for node in element_in:
if node.tag != GAZ_BLOCK_TAG:
self.unparse_node(node)
self.input += ") "
elif node.tag == GAZ_BLOCK_TAG:
self.unparse_node(node)
i += 1
def unparse_routine_call(self, element_in: ET.Element):
pass
def unparse_statement(self, element_in: ET.Element):
pass
def unparse_top_block(self, element_in: ET.Element):
pass
def unparse_unary(self, element_in: ET.Element):
self.input += " {}".format(to_gaz_op(element_in.get("op")))
self._xhs_unparse(element_in.find(GAZ_RHS_TAG))
def unparse_expression(self, element_in: ET.Element):
pass

View file

@ -1,6 +1,6 @@
procedure main() returns integer {
var integer a = 1 ;
a * 42 -> std_output;
return 0 ;
var integer a = 1;
a * 42 -> std_output;
return 0;
}

View file

@ -1,13 +1,14 @@
import unittest
from ast_parser.gaz_unparser import AstParser
import xml.etree.ElementTree as ET
class TestParseCode(unittest.TestCase):
def test_unparse_variable_regular(self):
input = '<variable mut="var" type="int" name="a" ref_name="_lsiyjvtbvnpmlml"/>'
parser = AstParser(input, True)
parser = AstParser(ET.fromstring(input), True)
parser.input = ""
parser.unparse_node(parser.xml)
self.assertIsNotNone(parser.input)
@ -15,73 +16,135 @@ class TestParseCode(unittest.TestCase):
def test_unparse_variable_declaration(self):
input = '<variable mut="var" type="int" name="a" ref_name="_lsiyjvtbvnpmlml"/>'
parser = AstParser(input, True)
parser = AstParser(ET.fromstring(input), True)
parser.input = ""
parser.unparse_variable(parser.xml, True)
self.assertIsNotNone(parser.input)
self.assertEqual("var integer a ", parser.input)
self.assertEqual("var integer a", parser.input)
def test_unparse_rhs_single(self):
input = '<rhs><literal type="int" value="1" /></rhs>'
parser = AstParser(input, True)
parser = AstParser(ET.fromstring(input), True)
parser.input = ""
parser.unparse_node(parser.xml)
self.assertIsNotNone(parser.input)
self.assertEqual(" 1 ", parser.input)
self.assertEqual("1", parser.input)
def test_unparse_declaration(self):
input = '<declaration><variable mut="var" type="int" name="a" ref_name="_lsiyjvtbvnpmlml"/><rhs><literal type="int" value="1" /></rhs></declaration>'
parser = AstParser(input, True)
parser = AstParser(ET.fromstring(input), True)
parser.input = ""
parser.unparse_node(parser.xml)
self.assertIsNotNone(parser.input)
self.assertEqual("var integer a = 1 ;\n", parser.input)
self.assertEqual("var integer a = 1;\n", parser.input)
def test_unparse_stream(self):
input = ' <stream type="std_output"> <operator op="*" type="unset"> <lhs> <variable mut="var" type="int" name="a" ref_name="_lsiyjvtbvnpmlml"/> </lhs> <rhs> <literal type="int" value="42" /> </rhs> </operator></stream>'
parser = AstParser(input, True)
parser = AstParser(ET.fromstring(input), True)
parser.input = ""
parser.unparse_node(parser.xml)
self.assertIsNotNone(parser.input)
self.assertEqual(" a * 42 -> std_output;\n", parser.input)
self.assertEqual("a * 42 -> std_output;\n", parser.input)
def test_unparse_block(self):
input = '<block> <declaration> <variable mut="var" type="int" name="a" ref_name="_lsiyjvtbvnpmlml"/> <rhs> <literal type="int" value="1" /> </rhs> </declaration> <stream type="std_output"> <operator op="*" type="unset"> <lhs> <variable mut="var" type="int" name="a" ref_name="_lsiyjvtbvnpmlml"/> </lhs> <rhs> <literal type="int" value="42" /> </rhs> </operator> </stream> <return> <literal type="int" value="0" /> </return> </block>'
parser = AstParser(input, True)
parser = AstParser(ET.fromstring(input), True)
parser.input = ""
parser.unparse_node(parser.xml)
self.assertIsNotNone(parser.input)
self.assertEqual("{\n var integer a = 1 ;\n a * 42 -> std_output;\n return 0 ;\n}\n\n", parser.input)
self.assertEqual("{\n var integer a = 1;\n a * 42 -> std_output;\n return 0;\n}\n\n", parser.input)
def test_unparse_assignment(self):
with open("xml/assignment.xml", "r") as f:
input = f.read()
parser = AstParser(ET.fromstring(input), True)
parser.input = ""
parser.unparse_node(parser.xml)
self.assertIsNotNone(parser.input)
self.assertEqual("C = 30;\n", parser.input)
def test_unparse_conditional(self): # TODO test the else-if statements
with open("xml/conditional.xml", "r") as f:
input = f.read()
with open("xml/conditional.out", "r") as f:
output = f.read()
parser = AstParser(ET.fromstring(input), True)
parser.input = ""
parser.unparse_node(parser.xml)
self.assertIsNotNone(parser.input)
self.assertEqual(output, parser.input)
def test_unparse_loop(self):
with open("xml/loop.xml", "r") as f:
input = f.read()
with open("xml/loop.out", "r") as f:
output = f.read()
parser = AstParser(ET.fromstring(input), True)
parser.input = ""
parser.unparse_node(parser.xml)
self.assertIsNotNone(parser.input)
self.assertEqual(output, parser.input)
def test_unparse_operation_single(self):
input = '<operator op="*" type="unset"> <lhs> <variable mut="var" type="int" name="a" ref_name="_lsiyjvtbvnpmlml"/> </lhs> <rhs> <literal type="int" value="42" /> </rhs> </operator>'
parser = AstParser(input, True)
input = '<operator op="multiplication" type="unset"> <lhs> <variable mut="var" type="int" name="a" ref_name="_lsiyjvtbvnpmlml"/> </lhs> <rhs> <literal type="int" value="42" /> </rhs> </operator>'
parser = AstParser(ET.fromstring(input), True)
parser.input = ""
parser.unparse_node(parser.xml)
self.assertIsNotNone(parser.input)
self.assertEqual(" a * 42 ", parser.input)
self.assertEqual("a * 42", parser.input)
def test_unparse_return(self):
input = '<return> <literal type="int" value="0" /> </return>'
parser = AstParser(input, True)
parser = AstParser(ET.fromstring(input), True)
parser.input = ""
parser.unparse_node(parser.xml)
self.assertIsNotNone(parser.input)
self.assertEqual("return 0 ;\n", parser.input)
self.assertEqual("return 0;\n", parser.input)
def test_unparse_unary(self):
with open("xml/unary.xml", "r") as f:
input = f.read()
with open("xml/unary.out", "r") as f:
output = f.read()
parser = AstParser(ET.fromstring(input), True)
parser.input = ""
parser.unparse_node(parser.xml)
self.assertIsNotNone(parser.input)
self.assertEqual(output, parser.input)
def test_unparse_routine(self):
input = '<procedure name="main" ref_name="_jemrvvseyj" return_type="int" args="()" ><block><declaration><variable mut="var" type="int" name="a" ref_name="_lsiyjvtbvnpmlml"/><rhs><literal type="int" value="1" /></rhs></declaration><stream type="std_output"><operator op="*" type="unset"><lhs><variable mut="var" type="int" name="a" ref_name="_lsiyjvtbvnpmlml"/></lhs><rhs><literal type="int" value="42" /></rhs></operator></stream><return><literal type="int" value="0" /></return></block></procedure>'
parser = AstParser(input, True)
parser = AstParser(ET.fromstring(input), True)
parser.input = ""
parser.unparse_node(parser.xml)
self.assertIsNotNone(parser.input)
i = ' ' * parser.indentation
self.assertEqual("procedure main() returns integer {\n var integer a = 1 ;\n a * 42 -> std_output;\n return 0 ;\n}\n\n", parser.input)
self.assertEqual("procedure main() returns integer {\n var integer a = 1;\n a * 42 -> std_output;\n return 0;\n}\n\n", parser.input)
def test_unparse_args(self):
with open("xml/many_args.xml", 'r') as f:
input = f.read()
with open("xml/many_args.out", 'r') as f:
output = f.read()
parser = AstParser(ET.fromstring(input), True)
parser.input = ""
parser.unparse_node(parser.xml)
self.assertIsNotNone(parser.input)
self.assertEqual(output, parser.input)
def test_unparse_code(self):
with open("test.xml", "r") as input:
parser = AstParser(input.read(), True)
with open("xml/test.xml", "r") as input:
parser = AstParser(ET.fromstring(input.read()), True)
parser.unparse()
self.assertIsNotNone(parser.input)

View file

@ -0,0 +1,6 @@
<assignment>
<variable name="C" type="int" mut="var"/>
<rhs>
<literal type="int" value="30"/>
</rhs>
</assignment>

View file

@ -0,0 +1,5 @@
if (false) {
return 0;
} else {
return 1;
}

View file

@ -0,0 +1,13 @@
<conditional>
<literal type="bool" value="False"/>
<block type="true">
<return>
<literal type="int" value="0" />
</return>
</block>
<block type="false">
<return>
<literal type="int" value="1" />
</return>
</block>
</conditional>

View file

@ -0,0 +1,4 @@
loop (true) {
a * 42 -> std_output;
}

View file

@ -0,0 +1,15 @@
<loop>
<literal type="bool" value="True"/>
<block>
<stream type="std_output">
<operator op="*" type="unset">
<lhs>
<variable mut="var" type="int" name="a" ref_name="_pseeixbzvvhuygw"/>
</lhs>
<rhs>
<literal type="int" value="42" />
</rhs>
</operator>
</stream>
</block>
</loop>

View file

@ -0,0 +1,4 @@
procedure beeeeees(integer a, integer b, integer bb, integer bbb, integer bbbb, integer bbbbb, integer bbbbbb, integer bbbbbbb, integer bbbbbbbb) returns integer {
return 0;
}

View file

@ -0,0 +1,16 @@
<procedure name="beeeeees" return_type="int">
<argument name="a" type="int"/>
<argument name="b" type="int"/>
<argument name="bb" type="int"/>
<argument name="bbb" type="int"/>
<argument name="bbbb" type="int"/>
<argument name="bbbbb" type="int"/>
<argument name="bbbbbb" type="int"/>
<argument name="bbbbbbb" type="int"/>
<argument name="bbbbbbbb" type="int"/>
<block>
<return>
<literal type="int" value="0" />
</return>
</block>
</procedure>

View file

@ -0,0 +1 @@
-3

View file

@ -0,0 +1,5 @@
<unary op="negation" type="int">
<rhs>
<literal type="int" value="3"/>
</rhs>
</unary>

View file

@ -1,6 +1,8 @@
import yaml
import ast_parser
import ast_generator
from ast_generator.ast_generator import *
from ast_parser.gaz_unparser import *
class GazpreaFuzzer:
def __init__(self, config: str):
@ -11,5 +13,16 @@ class GazpreaFuzzer:
self.settings = settings
self.parser = None
self.generator = ast_generator.AstGenerator()
self.generator = AstGenerator(settings)
self.ast = None
self.source = None
self.out = None
def fuzz(self):
self.generator.generate_ast()
self.parser = AstParser(self.generator.ast, True)
self.parser.unparse()
self.ast = self.generator.ast
self.source = self.parser.input

29
fuzzer/input/name9.in Normal file
View file

@ -0,0 +1,29 @@
procedure main() returns integer {
var integer lQnOqNtVPW = 698.7344103570729 * -606.7195181938484 + 1182583819 / 338469442 -132074245 237434130 * -708692944 / 530298228 / 228341377 * -1043540342 / 338.5382125746569 - -1560602812 2034076062 -677.2384366071922 * -1396288472 / -294.03910951537273 / 280.6003642162291 * 686277004 + -733.108807335117 - 1914739986 + -758706778 815.5612439852075 - 730843697 / -2035135312 761.468341780042 - 829972738;
529.6931700408081 * -53.71572853074235 - 731650703 263042418 * 1435010036 * -737.690803185421 - -395.5236453408153 / 1196211792 * -863.1836123458379 * -749.2669025070672 / 233.51151490705547 * -51.0686729564427 + -621.939364952389 / -361.3032921336703 - 1199853509 + 907542641 - 305.66149149183957 - -969.8710268189419 + 740.6073234896774 * 1719139590 - -243.75739859831253 - 1996675237 -> std_output;
var integer HWk = 1069696775;
var integer MIk = 1514360961;
var integer HE = -649.8393258588937 * -420.15021805874414 * 1761285701 -1667293001 / 29.5677167859983 * -844.2501263700528 / 1501314800 -1162542243 - -1217599986 + 1615995882 -1764940899 + -1917325853 + 835.4795594258562 * 590.6099641194992 - 472.7184791317236 * 1344256840 * 62.679409268019754 - 484.02060330123754 * 777.5221533723766 330.52965727523974 -380.69699980042685 * -760070929 * -949.6644980763808 - -447.8157902650353 * 464.1790468792867;
MIk = 953967969 + -268.8694010427613 / 791.5413559693457 + -7.679861742818616 / 1437831656 + 403.979481098871 * -456304863 - 2091190143 * 737295943 -1039468631 / -681.5757290664048 + -971.7430559091156 * -445.84393937984385 * -222.0375737233644 1070575402 -999.5935819561656 - -173.41289931519555 -1190366598 / 613.2734677906551 -531818545;
-397.7646630448985 - 1809763600 -982.6387961874157 + 256902008 * 425.58253894287964 / -718.3862648199979 -429.5886775058759 * 158.12171431595698 * -599.7405849078852 -733.8460310316564 * -742.5867261833964 * 2086150131 - 703.2177962216272 -> std_output;
lQnOqNtVPW = -680.8890396739438;
HWk = -254718851 / 264.0381140059085 * 996.2297492346818 - -77.96516420152841;
2100864484 - 2007894240 * -212.01378334488163 * 1379091426 -412243492 / -317390514 1229512655 / 1726566479 / 1747747042 764692152 + 624951054 + -1324352806 + 399.1702565288206 + -893.8711860029409 + -711.4400942267645 + 179.0145034263055 - -723.3632700757751 -2079239194 * -729.6073740027866 + -629.3818640065572 * 142789298 / -489.50899343461106 - 561691654 + -1414809862 * 222.37308869516414 / 857.1114294659471 549.7759000995088 + -666.6748642112184 * 385.38510100490385 -> std_output;
return 0;
HWk = 2059289556 + -403.9892396676721 / 1653655432 - -588.6575838596884 * -467.74405479942334 -789.6678603205703 - -2079730883 * -206.976327703003 - -99.23168409674201 -368.21174081123957 -2125902669 * 721.014283295284 * 684.9390791239739 * -336.9272218346822 / -549.8949978968651 / 31.821007498567496 / -386544376 36.406643230034206 -979.8695533308437 - -405.3890042820476 + -241343604 * 947.4009884595018 * -741574263;
}
procedure DzeIKcCNqh(integer rejZppcSMv, integer LkOieFctp, integer r, integer fGPZCKaJ, integer wLK, integer AeUntf, integer MWsHdvBSR, integer OuXoynGm, integer VPVOgzU, integer SMxhab) returns integer {
NAsBez = 807.1145861289976;
-1046538300 -> std_output;
return -211048078;
}
function UkU(integer ImmgbVHS, integer LfvBpxnRq) returns integer {
NAsBez = 961878732;
return -1293956197 / -773.5583114264432 / 759992758 - 324.6814914711299 / -773.3733374415364 * -823.4158348051863 * -1178415147 / 749.7213693296735 - -131.4240459218521 - -607197268 * -71900919 768.0290042747429 * 1529150661 * -657.5023412274927 / -201.66669058694868 / 692.9818240317327 / -1241350558 / -652.1792880359916 * 673.9253031170642 -61.25909942165197 * -2037670958 -1400547457 - 588219524 / -539.7564210381759 * 1856853047 / -1654156060 + -648756285;
NAsBez = 186.7935151585625 + 439669401 / 545.2783919286676 - -53306996 -9214657 - 184.5664265585533 / 291945719 * -443885835 + -566896102 - -346.630385606735 / 990.8304675995412 1582261953 - -1818951954 - -80664147 - 466.8821342017786 / 459.0521603737384 249.74968247519246;
var integer xtoZPgYmq = 810.2648762093065 / 482.261574544076 * 1927906771 / 630.1087104660135 -860.8294002903949 / 1932738597 + 1967595112 + -1136874252 * 580228054 -344.98371454114204 * -528.4467764471448 * 1842148455 + -166.07081934179928 / 90.4861524809719 / -177909614 / 2014149666;
var integer MmXWOxIXst = -135150791 / -842.279867288959 -873.3805968639836 + 137.73347301182048 + -668.6167365403119 - -531.4895607809302 - -486203036 / 1163466657 / -1996539944 * 908219867 * 684.3378150732071 - -351.83526537527894 / 569.8408814272439 * 1560698923;
}

View file

@ -1,83 +1,59 @@
import json
from xml import etree
import os
import random
from fuzzingbook import Grammars
from fuzzingbook.Grammars import is_valid_grammar
from isla.solver import ISLaSolver
import yaml
import fuzzer as fz
import argparse
import ast_generator.ast_generator
from ast_parser.ast_solver import AstSolver
from ast_parser.gaz_unparser import AstParser
from ast_generator import gazprea_ast_grammar
import xml.etree.ElementTree as ET
import xml.dom.minidom
import ast_parser
import xml.etree.ElementTree as ET
class Fuzzer():
def __init__(self, config: str, batch: int, seed: str):
with open(config) as yaml_file:
settings: dict = yaml.safe_load(yaml_file)
self.settings = settings
self.batch = batch
random.seed(seed)
self.fuzzer = fz.GazpreaFuzzer(config)
self.fuzzer.fuzz()
class GazpreaFuzzer(ISLaSolver):
"""Produce Gazprea code"""
def __init__(self,
grammar: Grammars,
start_symbol: str = "<start>",
constraint: str = "",
**kwargs) -> None:
"""
@brief initialize a Gazprea code generator
:param grammar: the grammar from which you would like to generate code
:param start_symbol: the start symbol of the grammar (default "<start>")
:param constraint: any constraints that you would like to impose on the solver
:param kwargs: any extra arguments passed to the ISLaSolver
"""
assert start_symbol in grammar
assert is_valid_grammar(grammar)
super().__init__(grammar, constraint, start_symbol=start_symbol, **kwargs)
def fuzz(self) -> str:
"""Produce the hecking code"""
AST = AstParser(eval(str(self.solve())), from_xml=True)
AstSolver.fix_missing_locations(AST)
AST.unparse()
return AST.input
def fuzz(self):
for i in range(self.batch):
self.fuzzer.fuzz()
dom = xml.dom.minidom.parseString(ET.tostring(self.fuzzer.ast).decode('utf-8'))
pretty: str = dom.toprettyxml()
os.system("rm -rf fuzzer")
os.mkdir("fuzzer")
os.mkdir("fuzzer/input")
os.mkdir("fuzzer/debug")
os.mkdir("fuzzer/instream")
os.mkdir("fuzzer/outputs")
with open("fuzzer/input/name{}.in".format(i), 'w') as f:
f.write(self.fuzzer.source)
with open("fuzzer/debug/name{}.out".format(i), 'w') as f:
f.write(pretty)
# with open("fuzzer/instream/{}.in".format(i), 'w') as f:
# f.write(self.fuzzer.source)
# with open("fuzzer/outputs/{}.out".format(i), 'w') as f:
# f.write(self.fuzzer.out)
if __name__ == '__main__':
gen = ast_generator.ast_generator.AstGenerator(gazprea_ast_grammar.GAZPREA_TOP_LEVEL, json.loads('{}'))
with open("debug/test.xml", 'w') as t:
et = gen.generate_ast()
dom = xml.dom.minidom.parseString(ET.tostring(et).decode('utf-8'))
pretty: str = dom.toprettyxml()
repretty = ""
for line in pretty.split('\n'):
if line.startswith("<?xml"):
pass
else:
repretty += (line + '\n')
parser = argparse.ArgumentParser(
description='Procedurally generate a test case for Gazprea'
)
parser.add_argument('-b', '--batch_size', type=int, required=False,
help="generate BATCH cases (fuzzer/input/nameX.in, /instream/..., /outputs/...)")
parser.add_argument('--seed', type=int, required=False, action="store",
help="rng seed")
parser.add_argument('config_file', type=str, action="store",
help="path to your configuration file")
t.write(repretty)
gen.populate_ast(et)
with open("debug/populated.xml", 'w') as t:
dom = xml.dom.minidom.parseString(ET.tostring(et).decode('utf-8'))
pretty: str = dom.toprettyxml()
repretty = ""
for line in pretty.split('\n'):
if line.startswith("<?xml"):
pass
else:
repretty += (line + '\n')
t.write(repretty)
source = ast_parser.ast_parser.AstParser(et, from_xml=True)
source.unparse()
with open("debug/test.gz", 'w') as t:
t.write(source.input)
args = parser.parse_args()
fuzzer = Fuzzer(config=args.config_file, batch=args.batch_size, seed=args.seed)
fuzzer.fuzz()