Coverage for /pythoncovmergedfiles/medio/medio/src/fuzz_lex_yacc.py: 40%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

52 statements  

1###### Coverage stub 

2import atexit 

3import coverage 

4cov = coverage.coverage(data_file='.coverage', cover_pylib=True) 

5cov.start() 

6# Register an exist handler that will print coverage 

7def exit_handler(): 

8 cov.stop() 

9 cov.save() 

10atexit.register(exit_handler) 

11####### End of coverage stub 

12#!/usr/bin/python3 

13# Copyright 2022 Google LLC 

14# 

15# Licensed under the Apache License, Version 2.0 (the "License"); 

16# you may not use this file except in compliance with the License. 

17# You may obtain a copy of the License at 

18# 

19# http://www.apache.org/licenses/LICENSE-2.0 

20# 

21# Unless required by applicable law or agreed to in writing, software 

22# distributed under the License is distributed on an "AS IS" BASIS, 

23# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

24# See the License for the specific language governing permissions and 

25# limitations under the License. 

26"""Fuzzer that creates a simple grammar and parsing routines, 

27and then uses that to parse the fuzzer data. The grammer and 

28parsing routines can be extended based on coverage analysis.""" 

29 

30import sys 

31import atheris 

32import ply.lex as lex 

33import ply.yacc as yacc 

34 

35 

36# A simple lexer 

37tokens = [ 

38 "PLUS", 

39 "MINUS", 

40 "TIMES", 

41 "NUMBER", 

42 ] 

43 

44t_PLUS = r'\+' 

45t_MINUS = r'-' 

46t_TIMES = "\*" 

47t_ignore = ' \t' 

48 

49def t_NUMBER(t): 

50 r'\d+' 

51 t.value = int(t.value) 

52 return t 

53 

54def t_ignore_newline(t): 

55 r'\n+' 

56 t.lexer.lineno += t.value.count('\n') 

57 

58def t_error(t): 

59 pass 

60 

61 

62# Some simple parser rules. Note that grammar rules are written as docstrings 

63# in each function. 

64def p_expression(p): 

65 ''' 

66 expression : term PLUS term 

67 | term MINUS term 

68 ''' 

69 p[0] = ('binop', p[2], p[1], p[3]) 

70 

71 

72def p_expression_term(p): 

73 ''' 

74 expression : term 

75 ''' 

76 p[0] = p[1] 

77 

78def p_term(p): 

79 ''' 

80 term : factor TIMES factor 

81 ''' 

82 p[0] = ('binop', p[2], p[1], p[3]) 

83 

84def p_term_factor(p): 

85 ''' 

86 term : factor 

87 ''' 

88 p[0] = p[1] 

89 

90def p_factor_number(p): 

91 ''' 

92 factor : NUMBER 

93 ''' 

94 p[0] = ('number', p[1]) 

95 

96def p_error(p): 

97 pass 

98# end of parser functions 

99 

100def TestOneInput(data): 

101 fdp = atheris.FuzzedDataProvider(data) 

102 lex.lex() 

103 parser = yacc.yacc() 

104 try: 

105 parser.parse(fdp.ConsumeUnicodeNoSurrogates(sys.maxsize)) 

106 except lex.LexError: 

107 pass 

108 

109def main(): 

110 atheris.instrument_all() 

111 atheris.Setup(sys.argv, TestOneInput, enable_python_coverage=True) 

112 atheris.Fuzz() 

113 

114if __name__ == "__main__": 

115 main()