Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Fuzzing Without Specifications: Learning Struct...

Fuzzing Without Specifications: Learning Structure from Behaviour Part II

Avatar for Rahul Gopinath

Rahul Gopinath

June 04, 2025
Tweet

More Decks by Rahul Gopinath

Other Decks in Research

Transcript

  1. 7 Random Fuzzing $ ./fuzz [;x1-GPZ+wcckc];,N9J+?#6^6\e?]9lu
 2_%'4GX"0VUB[E/r ~fApu6b8<{%siq8Z
 h.6{V,hr?;{Ti.r3PIxMMMv6{xS^+'Hq!
 AxB"YXRS@!Kd6;wtAMefFWM(`|J_<1~o}


    z3K(CCzRH JIIvHz>_*.\>JrlU32~eGP?
 lR=bF3+;y$3lodQ<B89!5"W2fK*vE7v{'
 )KC-i,c{<[~m!]o;{.'}Gj\(X}EtYetrp
 bY@aGZ1{P!AZU7x#4(Rtn!q4nCwqol^y6
 }0|Ko=*JK~;zMKV=9Nai:wxu{J&UV#HaU
 )*BiC<),`+t*gka<W=Z.%T5WGHZpI30D<
 Pq>&]BS6R&j?#tP7iaV}-}`\?[_[Z^LBM
 PG-FKj'\xwuZ1=Q`^`5,$N$Q@[!CuRzJ2
 D|vBy!^zkhdf3C5PAkR?V((-%><hn|3='
 i2Qx]D$qs4O`1@fevnG'2\11Vf3piU37@
 5:dfd45*(7^%5ap\zIyl"'f,$ee,J4Gw:
 cgNKLie3nx9(`efSlg6#[K"@WjhZ}r[Sc
 un&sBCS,T[/3]KAeEnQ7lU)3Pn,0)G/6N
 -wyzj/MTd#A;r*(ds./df3r8Odaf?/<#r Program ✘
  2. • Insert Instrumentation • Generate inputs • Collect execution feedback

    • Branches covered during execution • Slightly Mutate Input and try again Collect inputs obtaining new coverage 8 Coverage Guided Fuzzing triangle (1,1,2) def triangle(a, b, c): if a == b: if b == c: return Equilateral else: return Isosceles else: if b == c: return Isosceles else: if a == c: return Isosceles else: return Scalene triangle (1,1,1) AFL 8
  3. Service topology map of Uber showing hundreds of microservices (Source:

    Uber Engineering) Instrumentation ability or source code access is not always guaranteed
  4. 14 Fuzzing Blackbox Parsers $ ./fuzz [;x1-GPZ+wcckc];,N9J+?#6^6\e?]9lu
 2_%'4GX"0VUB[E/r ~fApu6b8<{%siq8Z
 h.6{V,hr?;{Ti.r3PIxMMMv6{xS^+'Hq!


    AxB"YXRS@!Kd6;wtAMefFWM(`|J_<1~o}
 z3K(CCzRH JIIvHz>_*.\>JrlU32~eGP?
 lR=bF3+;y$3lodQ<B89!5"W2fK*vE7v{'
 )KC-i,c{<[~m!]o;{.'}Gj\(X}EtYetrp
 bY@aGZ1{P!AZU7x#4(Rtn!q4nCwqol^y6
 }0|Ko=*JK~;zMKV=9Nai:wxu{J&UV#HaU
 )*BiC<),`+t*gka<W=Z.%T5WGHZpI30D<
 Pq>&]BS6R&j?#tP7iaV}-}`\?[_[Z^LBM
 PG-FKj'\xwuZ1=Q`^`5,$N$Q@[!CuRzJ2
 D|vBy!^zkhdf3C5PAkR?V((-%><hn|3='
 i2Qx]D$qs4O`1@fevnG'2\11Vf3piU37@
 5:dfd45*(7^%5ap\zIyl"'f,$ee,J4Gw:
 cgNKLie3nx9(`efSlg6#[K"@WjhZ}r[Sc
 un&sBCS,T[/3]KAeEnQ7lU)3Pn,0)G/6N
 -wyzj/MTd#A;r*(ds./df3r8Odaf?/<#r Parser Syntax Error Interpreter #
  5. 15 Fuzzing Blackbox Parsers $ ./fuzz -g grammar ..................................
 ..................................


    ..................................
 ..................................
 ..................................
 ..................................
 ..................................
 ..................................
 ..................................
 ..................................
 ..................................
 ..................................
 ..................................
 ..................................
 .................................. Parser Parsed! Interpreter ✓ Grammar
  6. 16 Formal Languages Formal Language Descriptions 3. Regular Context Free

    Recursively Enumerable (Chomsky,1956) Possible to infer Argument Stack Return Stack
  7. 17 Fuzzing Blackbox Parsers $ ./fuzz -g grammar ..................................
 ..................................


    ..................................
 ..................................
 ..................................
 ..................................
 ..................................
 ..................................
 ..................................
 ..................................
 ..................................
 ..................................
 ..................................
 ..................................
 .................................. Parser Parsed! Interpreter ✓ Grammar
  8. 18 Where to Get the Grammar From? "Be liberal in

    what you accept, and conservative in what you send"
 (the cause of trouble) Postel's Law
  9. 20 The standard spec Buggy Implementation "Extra" Features "Accepted" Bugs

    •Reference Specification? "Be liberal in what you accept, and conservative in what you send"
 (the cause of trouble) Postel's Law
  10. 24 Grammar Inference (L*) L* (Angluin'84) Learner membership: w ∈

    L? equivalence: G = L? yes/no counterexample yes/no Teacher
  11. 26

  12. 27 Grammar Inference (L*) ɛ ɛ 0 S Observation Table

    E Language (L): {s ∈ Σ* : #b's = 1 } Alphabet (Σ) : {a, b} T is Closed (states): ∀ w∈S⋅ Σ, ∃ s ∈ S such that [w,]=[s,] If not closed, add the counter example to S T is Consistent (transitions): ∀ s1,s2∈S, if row(s1) = row(s2) then ∀ a ∈ A [s1a,]=[s2a,] If not consistent, add the counter example to E We begin with S = {ɛ} and E = {ɛ} a 0 b 1 S · Σ
  13. 28 Grammar Inference (L*) ɛ ɛ 0 S Observation Table

    E Alphabet (Σ) : {a, b} T is Closed: ∀ w∈S⋅ Σ, ∃ s ∈ S such that [w,]=[s,] If not closed, add the counter example to S T is Consistent: ∀ s1,s2∈S, if row(s1) = row(s2) then ∀ a ∈ A [s1a,]=[s2a,] If not consistent, add the counter example to E We begin with S = {ɛ} and E = {ɛ} a 0 b 1 S · Σ Language (L): {s ∈ Σ* : #b's = 1 }
  14. 29 Grammar Inference (L*) ɛ ɛ 0 b 1 Observation

    Table S E a 0 ba 1 bb 0 S · Σ T is Closed: ∀ w∈S⋅ Σ, ∃ s ∈ S such that [w,]=[s,] If not closed, add the counter example to S T is Consistent: ∀ s1,s2∈S, if row(s1) = row(s2) then ∀ a ∈ A [s1a,]=[s2a,] If not consistent, add the counter example to E Language (L): {s ∈ Σ* : #b's = 1 } Alphabet (Σ) : {a, b}
  15. 30 Grammar Inference (L*) ɛ ɛ 0 b 1 Observation

    Table S E a 0 ba 1 bb 0 S · Σ T is Closed: ∀ w∈S⋅ Σ, ∃ s ∈ S such that [w,]=[s,] If not closed, add the counter example to S T is Consistent: ∀ s1,s2∈S, if row(s1) = row(s2) then ∀ a ∈ A [s1a,]=[s2a,] If not consistent, add the counter example to E Language (L): {s ∈ Σ* : #b's = 1 } Alphabet (Σ) : {a, b}
  16. 31 Grammar Inference (L*) ɛ ɛ 0 b 1 Observation

    Table S E a 0 ba 1 bb 0 S · Σ T is Closed: ∀ w∈S⋅ Σ, ∃ s ∈ S such that [w,]=[s,] If not closed, add the counter example to S T is Consistent: ∀ s1,s2∈S, if row(s1) = row(s2) then ∀ a ∈ A [s1a,]=[s2a,] If not consistent, add the counter example to E Alphabet (Σ) : {a, b} Language (L): {s ∈ Σ* : #b's = 1 }
  17. 32 Grammar Inference (L*) ɛ ɛ 0 b 1 Observation

    Table S E a 0 ba 1 bb 0 S · Σ T is Closed: ∀ w∈S⋅ Σ, ∃ s ∈ S such that [w,]=[s,] If not closed, add the counter example to S T is Consistent: ∀ s1,s2∈S, if row(s1) = row(s2) then ∀ a ∈ A [s1a,]=[s2a,] If not consistent, add the counter example to E Alphabet (Σ) : {a, b} Language (L): {s ∈ Σ* : #b's = 1 }
  18. 33 Grammar Inference (L*) Observation Table E T is Closed:

    ∀ w∈S⋅ Σ, ∃ s ∈ S such that [w,]=[s,] If not closed, add the counter example to S T is Consistent: ∀ s1,s2∈S, if row(s1) = row(s2) then ∀ a ∈ A [s1a,]=[s2a,] If not consistent, add the counter example to E <$ɛ>:= a <$ɛ> | b <$b> <$b>:= a <$b> | b <$ɛ> | ɛ ɛ ɛ 0 b 1 S a 0 ba 1 bb 0 S · Σ Alphabet (Σ) : {a, b} Language (L): {s ∈ Σ* : #b's = 1 }
  19. 34 Grammar Inference (L*) Observation Table S E T is

    Closed: ∀ w∈S⋅ Σ, ∃ s ∈ S such that [w,]=[s,] If not closed, add the counter example to S T is Consistent: ∀ s1,s2∈S, if row(s1) = row(s2) then ∀ a ∈ A [s1a,]=[s2a,] If not consistent, add the counter example to E bbb ✘ <ɛ> := a <ɛ> | b <b> <b> := a <b> | b <ɛ> | ɛ ɛ ɛ 0 b 1 a 0 ba 1 bb 0 S · Σ Alphabet (Σ) : {a, b} Language (L): {s ∈ Σ* : #b's = 1 }
  20. 35 Grammar Inference (L*) ɛ ɛ 0 b 1 bb

    0 bbb 0 Observation Table S E T is Closed: ∀ w∈S⋅ Σ, ∃ s ∈ S such that [w,]=[s,] If not closed, add the counter example to S T is Consistent: ∀ s1,s2∈S, if row(s1) = row(s2) then ∀ a ∈ A [s1a,]=[s2a,] If not consistent, add the counter example to E Alphabet (Σ) : {a, b} Language (L): {s ∈ Σ* : #b's = 1 }
  21. 36 Grammar Inference (L*) ɛ ɛ 0 b 1 bb

    0 bbb 0 Observation Table S E T is Closed: ∀ w∈S⋅ Σ, ∃ s ∈ S such that [w,]=[s,] If not closed, add the counter example to S T is Consistent: ∀ s1,s2∈S, if row(s1) = row(s2) then ∀ a ∈ A [s1a,]=[s2a,] If not consistent, add the counter example to E Alphabet (Σ) : {a, b} Language (L): {s ∈ Σ* : #b's = 1 }
  22. 37 Grammar Inference (L*) Observation Table S E a 0

    ba 1 bba 0 bbba 0 bbbb 0 S · Σ T is Closed: ∀ w∈S⋅ Σ, ∃ s ∈ S such that [w,]=[s,] If not closed, add the counter example to S T is Consistent: ∀ s1,s2∈S, if row(s1) = row(s2) then ∀ a ∈ A [s1a,]=[s2a,] If not consistent, add the counter example to E ɛ ɛ 0 b 1 bb 0 bbb 0 Alphabet (Σ) : {a, b} Language (L): {s ∈ Σ* : #b's = 1 }
  23. 38 Grammar Inference (L*) Observation Table S E T is

    Closed: ∀ w∈S⋅ Σ, ∃ s ∈ S such that [w,]=[s,] If not closed, add the counter example to S T is Consistent: ∀ s1,s2∈S, if row(s1) = row(s2) then ∀ a ∈ A [s1a,]=[s2a,] If not consistent, add the counter example to E s1 = [ɛ,] 0 s2 = [bb,] 0 s1.a = [ɛb,] 1 s2.a = [bbb,] 0 ɛ ɛ 0 b 1 bb 0 bbb 0 Alphabet (Σ) : {a, b} Language (L): {s ∈ Σ* : #b's = 1 } a 0 ba 1 bba 0 bbba 0 bbbb 0 S · Σ b b
  24. 39 Grammar Inference (L*) Observation Table S E T is

    Closed: ∀ w∈S⋅ Σ, ∃ s ∈ S such that [w,]=[s,] If not closed, add the counter example to S T is Consistent: ∀ s1,s2∈S, if row(s1) = row(s2) then ∀ a ∈ A [s1a,]=[s2a,] If not consistent, add the counter example to E ɛ b ɛ 0 1 b 1 0 bb 0 0 bbb 0 0 Alphabet (Σ) : {a, b} Language (L): {s ∈ Σ* : #b's = 1 } a 0 1 ba 1 0 bba 0 0 bbba 0 0 bbbb 0 0 S · Σ
  25. 40 Grammar Inference (L*) Observation Table S E <$ɛ> :=

    a <$ɛ> | b <$b> <$b> := a <$b> | b <$bb> | ɛ <$bb>:= a <$bb> | b <$bb> ɛ b ɛ 0 1 b 1 0 bb 0 0 bbb 0 0 a 0 1 ba 1 0 bba 0 0 bbba 0 0 bbbb 0 0 S · Σ Alphabet (Σ) : {a, b} Language (L): {s ∈ Σ* : #b's = 1 }
  26. 41 Grammar Inference (L*) Observation Table S E <$ɛ> :=

    a <$ɛ> | b <$b> <$b> := a <$b> | ɛ ✓ ɛ b ɛ 0 1 b 1 0 bb 0 0 bbb 0 0 a 0 1 ba 1 0 bba 0 0 bbba 0 0 bbbb 0 0 S · Σ Alphabet (Σ) : {a, b} Language (L): {s ∈ Σ* : #b's = 1 }
  27. 42 Grammar Inference (L*) -Use a discrimination tree rather than

    an observation table -Minimise the counter examples through exponential backo ff and binary search of the su ffi x -Intuition LG(w) != BB(w) -So, there should be a short pre fi x
 u such that w = uv where they di ff er originally. Find it through binary search. v is then the distinguishing su ffi x. Minimise that su ff i x. -You need to only add all pre fi xes of u to S. -Remove su ff i xes that do not add any value. Improvements (TTT)
  28. 43 Grammar Inference (L*) Learner Teacher w G = L?

    Equivalences Queries are not possible in software engineering scenarios <$ɛ> := a <$ɛ> | b <$b> <$b> := a <$b> | ɛ Alphabet (Σ) : {a, b} Language (L): {s ∈ Σ* : #b's = 1 } ✓
  29. 44 Grammar Inference (L*) Learner Teacher w G = L?

    Equivalences Queries are not possible in software engineering scenarios
  30. 45 L* Teacher with PAC Guarantees ab ✓ ✓ abb

    ✘ ✘ bb ✓ ✓ aaaa ✓ ✓ bbb ✓ ✘
  31. 46 L* Teacher with PAC Guarantees ab ✓ ✓ abb

    ✘ ✘ bb ✓ ✓ aaaa ✓ ✓ bbb ✘ ✘ aaa ✘ ✘ abab ✘ ✘
  32. 47 L* Teacher with PAC Guarantees Probably Approximately Correct (Valiant'84)

    Pr(L(A)≢X ≤ ϵ) ≥ 1−δ 1-∈: accuracy 1-δ: confidence Equivalence Query = Multiple Membership Checks Checks come from some sampling distribution D over A* We only get a PAC guarantee based on D qi = [1/ϵ (ln(1/δ) + i ln(2))] Checks made in place of ith equivalence query:
  33. 48 Grammar Inference (L*) Learner Oracle Membership Checks substitute Equivalence

    Queries w <ɛ> := a <ɛ> | b <b> <b> := a <b> | b <bb> | ɛ <bb> := a <bb> | b <bb> Alphabet (Σ) : {a, b} Language (L): {s ∈ Σ* : #b's = 1 }
  34. 49 Grammar Inference (PAC-L*) Learner Oracle w Random Sampler (D)

    Blackbox Hypothesis w ∈ D L(*) Substituting Equivalence Queries ab ✓ ✓ abb ✘ ✘ bb ✓ ✓ aaaa ✓ ✓ bbb ✓ ✘
  35. 50 Grammar Inference (PAC-L*) Learner Oracle w Random Sampler (D)

    w ∈ D L(*) Substituting Equivalence Queries Search Space
  36. 56 • Differentiate incomplete and incorrect inputs Key Idea: Viable

    Pre fi xes 56 • Solve one character at a time systematically
  37. 57 Example Generator a [ 5 1 b , }

    4 ] a ∉ [,],{,},",0,1,2,3,4,5,.,. b ∉ [,],0,1,2,3,4,5,6,7,8,9,, } ∉ [,],0,1,2,3,4,5,6,7,8,9,0,, [51,4] 57
  38. 58 Pre fi xQ AFL(black) INI 62.5 65 CSV 65.7

    68.3 JSON 13.8 9.2 TinyC 86.8 47.9 MJS 28.0 19.0 Quality of Examples Branch Coverage Obtained C programs
  39. 59 Pre fi xQ AFL(black) AFL(gray) INI 62.5 65 77.5

    CSV 65.7 68.3 68.5 JSON 13.8 9.2 22.5 TinyC 86.8 47.9 81.6 MJS 28.0 19.0 29.9 Quality of Examples Tex Crash: ]9xdy[zSf$\theta{f!;} ;i\nonfrenchspacing !$$\prec q;7O/, $\downbrace fi ll @Pz \mathstrut{}$^: aK[X|?$47$ ,`D f$)Cg8$* Branch Coverage Obtained C programs
  40. 60

  41. 61 Positive and Negative Examples with Pre fi x Queries

    a [ 5 1 b , } 4 ] a ∉ [,],{,},",0,1,2,3,4,5,.,. b ∉ [,],0,1,2,3,4,5,6,7,8,9,, } ∉ [,],0,1,2,3,4,5,6,7,8,9,0,, [51,4] 61
  42. 62 Grammar Inference (PL*) Learner Pre fi x Oracle w

    Blackbox Hypothesis w ∈ B Yes/No Yes/No PL(*) w ∈ H Substituting Equivalence Queries
  43. 63 Grammar Inference (PL*) Pr(L(A)≢X ≤ ϵ) ≥ 1−δ Relation

    between D,ϵ,δ and F1 score On Arithmetic (depth limited) L(*) Eq = Pre fi x Sampler Eq = Pre fi x Sampler) (p=0.05) (p=0.5) Eq = Pre fi x Sampler) (p=1.0) Red is good, Blue is bad PL(*) PL(*) PL(*) 1-δ: confidence 1-∈: accuracy
  44. 64 Grammar Inference (PL*) Pr(L(A)≢X ≤ ϵ) ≥ 1−δ Relation

    between D,ϵ,δ and F1 score On JSON (depth limited) L(*) Eq = Pre fi x Sampler (p=0.05) Eq = Pre fi x Sampler) (p=0.5) Eq = Pre fi x Sampler) (p=1.0) Red is good, Blue is bad 1-δ: confidence 1-∈: accuracy PL(*) PL(*) PL(*)
  45. 65

  46. Why Did My Program Crash? 8.2 - 27 - -9

    / +((+9 * --2 + --+-+-((-1 * +(8 - 5 - 6)) * (-(a-+(((+(4))))) - ++4) / +(-+---((5. 6 - --(3 * -1.8 * +(6 * +-(((-(-6) * ---+6)) / +- -(+-+-7 * (-0 * (+(((((2)) + 8 - 3 - ++9.0 + ---( --+7 / (1 / +++6.37) + (1) / 482) / +++-+0)))) + 8.2 - 27 - -9 / +((+9 * --2 + --+-+-((-1 * +(8 - 5 - 6)) * (-(a-+(((+(4))))) - ++4) / +(-+---((5.6 - --(3 * -1.8 * +(6 * +-(((-(-6) * ---+6)) / +-- (+-+-7 * (-0 * (+(((((2)) + 8 - 3 - ++9.0 + ---(- -+7 / (1 / +++6.37) + (1) / 482) / +++-+0)))) * - +5 + 7.513)))) - (+1 / ++((-84)))))))) * ++5 / +- (--2 - -++-9.0)))) / 5 * --++090 + * -+5 + 7.513) ))) - (+1 / ++((-84)))))))) * 8.2 - 27 - -9 / +(( +9 * --2 + --+-+-((-1 * +(8 - 5 - 6)) * (-(a-+ (((+(4))))) - ++4) / +(-+---((5.6 - --(3 * -1.8 * +(6 * +-(((-(-6) * ---+6)) / +--(+-+-7 * (-0 * ( +(((((2)) + 8 - 3 - ++9.0 + ---(--+7 / (1 / +++6. 37) + (1) / 482) / +++-+0)))) * -+5 + 7.513)))) - (+1 / ++((-84)))))))) * ++5 / +-(--2 - -++-9.0))) ) / 5 * --++090 ++5 / +-(--2 - -++-9.0)))) / 5 * --++090 DD Minimized Input ((4)) 00000 ? ((5)) ? (++5) ? 68
  47. 69

  48. 70 Issue 386 from Rhino var A = class extends

    (class {}){}; Issue 2937 from Closure const [y,y] = []; var {baz:{} = baz => {}} = baz => {}; Issue 385 from Rhino {while ((l_0)){ if ((l_0)) {break;;var l_0; continue }0}} Issue 2842 from Closure Delta Minimization is useful but not su ff i cient
  49. ( ( 4 ) ) <start> := <expr> <expr> :=

    <term> ' + ' <expr> | <term> ' - ' <expr> | <term> <term> := <factor> ' * ' <term> | <factor> ' / ' <term> | <factor> <factor> := '+' <factor> | '-' <factor> | '(' <expr> ')' | <integer> '.' <integer> | <integer> <integer>:= <digit> <integer> | <digit> <digit> := [0-9] 71
  50. ( ( 4 ) ) <start> := <expr> <expr> :=

    <term> ' + ' <expr> | <term> ' - ' <expr> | <term> <term> := <factor> ' * ' <term> | <factor> ' / ' <term> | <factor> <factor> := '+' <factor> | '-' <factor> | '(' <expr> ')' | <integer> '.' <integer> | <integer> <integer>:= <digit> <integer> | <digit> <digit> := [0-9] 72
  51. ( ( 4 ) ) <start> := <expr> <expr> :=

    <term> ' + ' <expr> | <term> ' - ' <expr> | <term> <term> := <factor> ' * ' <term> | <factor> ' / ' <term> | <factor> <factor> := '+' <factor> | '-' <factor> | '(' <expr> ')' | <integer> '.' <integer> | <integer> <integer>:= <digit> <integer> | <digit> <digit> := [0-9] ✓ Did not reproduce the failure 1 * (2 - 3) 73
  52. ( ( 4 ) ) <start> := <expr> <expr> :=

    <term> ' + ' <expr> | <term> ' - ' <expr> | <term> <term> := <factor> ' * ' <term> | <factor> ' / ' <term> | <factor> <factor> := '+' <factor> | '-' <factor> | '(' <expr> ')' | <integer> '.' <integer> | <integer> <integer>:= <digit> <integer> | <digit> <digit> := [0-9] 74
  53. ( ( 4 ) ) <start> := <expr> <expr> :=

    <term> ' + ' <expr> | <term> ' - ' <expr> | <term> <term> := <factor> ' * ' <term> | <factor> ' / ' <term> | <factor> <factor> := '+' <factor> | '-' <factor> | '(' <expr> ')' | <integer> '.' <integer> | <integer> <integer>:= <digit> <integer> | <digit> <digit> := [0-9] c 75
  54. ( ( 4 ) ) <start> := <expr> <expr> :=

    <term> ' + ' <expr> | <term> ' - ' <expr> | <term> <term> := <factor> ' * ' <term> | <factor> ' / ' <term> | <factor> <factor> := '+' <factor> | '-' <factor> | '(' <expr> ')' | <integer> '.' <integer> | <integer> <integer>:= <digit> <integer> | <digit> <digit> := [0-9] c ✓ Did not reproduce the failure 1 + 3 + 4 76
  55. ( ( 4 ) ) <start> := <expr> <expr> :=

    <term> ' + ' <expr> | <term> ' - ' <expr> | <term> <term> := <factor> ' * ' <term> | <factor> ' / ' <term> | <factor> <factor> := '+' <factor> | '-' <factor> | '(' <expr> ')' | <integer> '.' <integer> | <integer> <integer>:= <digit> <integer> | <digit> <digit> := [0-9] c c 77
  56. 3 * 4 <start> := <expr> <expr> := <term> '

    + ' <expr> | <term> ' - ' <expr> | <term> <term> := <factor> ' * ' <term> | <factor> ' / ' <term> | <factor> <factor> := '+' <factor> | '-' <factor> | '(' <expr> ')' | <integer> '.' <integer> | <integer> <integer>:= <digit> <integer> | <digit> <digit> := [0-9] c c ✓ Did not reproduce the failure 78
  57. ( ( 4 ) ) <start> := <expr> <expr> :=

    <term> ' + ' <expr> | <term> ' - ' <expr> | <term> <term> := <factor> ' * ' <term> | <factor> ' / ' <term> | <factor> <factor> := '+' <factor> | '-' <factor> | '(' <expr> ')' | <integer> '.' <integer> | <integer> <integer>:= <digit> <integer> | <digit> <digit> := [0-9] c c c c c c c 79
  58. ( ( 1 - 2 ) ) <start> := <expr>

    <expr> := <term> ' + ' <expr> | <term> ' - ' <expr> | <term> <term> := <factor> ' * ' <term> | <factor> ' / ' <term> | <factor> <factor> := '+' <factor> | '-' <factor> | '(' <expr> ')' | <integer> '.' <integer> | <integer> <integer>:= <digit> <integer> | <digit> <digit> := [0-9] c c c c c c c ✘ reproduced the failure ( ( 1 - 2 ) ) 80
  59. ( ( 1 - 2 ) ) c c c

    c c c c ✘ ( ( 1 - 2 ) ) 81
  60. ( ( 1 - 2 ) ) c c c

    c c c c ✘ ( ( 1 - 2 ) ) ✘ ( ( 2 * 3 + 4 ) ) 82
  61. ( ( 1 - 2 ) ) c c c

    c c c c ✘ ( ( 1 - 2 ) ) ✘ ( ( 2 * 3 + 4 ) ) ✘ ( ( - 2 / 1 ) ) 83
  62. ( ( 1 - 2 ) ) c c c

    c c c c ✘ ( ( 1 - 2 ) ) ✘ ( ( 2 * 3 + 4 ) ) ✘ ( ( - 2 / 1 ) ) ✘ ( ( 98 - 0 ) ) 84
  63. <expr> ) ( ( ) ( ( ) 4 )

    ( ( 4 ) ) c c c c c c c A 85
  64. <expr> ) ( ( ) ( ( ) 4 )

    ( ( 4 ) ) c c c c c c c A 86
  65. ( ( 4 ) ) c c c c c

    c c A ( ( ) ) <expr> ( ( ) ) 4 Minimized Input Abstract Failure Inducing Input def check(parsed): if parsed.is_nested() and parsed.child.is_nested(): raise Exception() return input 87
  66. 88 <start F> := <expr F> <expr F> := <term

    F> ' + ' <expr> | <term> ' + ' <expr F> | <term F> ' - ' <expr> | <term> ' - ' <expr F> | <term F> <term F> := <factor F> ' * ' <term> | <factor> ' * ' <term F> | <factor F> ' / ' <term> | <factor> ' / ' <term F> | <factor F> <factor F> := '+' <factor F> | '-' <factor F> | '(' <expr F> ')' | '(' <expr F1> ')' <expr F1> := <term F2> <term F2> := <factor F3> <factor F3>:= '(' <expr> ')' ((1)) + 2 (23 * ((3)) - 34) (344- 4 + ((223))) (1) - 3 * 773 + (-22 + 1) 1798 - 889 / ((333-1)) * 2 / 3 + 1 34 + ((4)) -334 + (334 - (22) + 919 * 0 + 1 98435747+ 88 + (((0))) + (1) - 1 * 7 / 4 * 889 - 2 8 + ((8)) + --1 + 11223 / 344 - 39 + (1) - 456 + 134 / 45 437 + 8 - 1 * ((9 + ((1))) - 1 + 99111948 + 3 --1 + (112) - 2 + 445) + 0 74 + 334 + ((178 - 88 / (3393-1) * 1002 / 3 + 1+ 3439)) * 223 - 1233 + 334672 2 * ((9)) - (1798 - 889 / (333-1) * 2 / 3 + 100012 + 3434392 + 234 ----6 * 1798 - 889 / (33 778 - (((1) - 3 * 773 + (-22 + 1) * (4545) - 23 - ((2)) * 773 + (-22 + 1) / 3434 + ---1 + 1 / 34343 + 112 349 + (((1) - 3 * 3 + (-22 + 1) ((+ (-22 + 1) * (4545) - 23 - (2) * 773 + ((-22 + 1)) / 3434 + ---1 + 1 / 34343 + 1123 8 + ((8)) + --1 + / 1 - 39 + (1) - 456 + 134 / 45 ))(((1) - 2334 + ((((1)) - 3 * 773 + (-22 + 1) * (2) - 23 - (2) * 773 + (-22 + 1) / 3 74 + 3 + ((178 - 88 / (3393-1) * 1002 / 3 + 1+ 3439)) * - 1233 + 334672)) ((8 + ((8)) + --1 + / 344 - 39 + (1) - 456 + 134 / 45 ))(((1) - 3 * 773 1+ 33+ 24343433 +23343 - ((74 + 334 + ((178 - 88 / (3393-1) * 1002 / 3 + 1+ 3439)) * - 1233 + 334672)) ((8 + ((8)) + --1 + / 344 - 39 + (1) - 456 + 134 / 4 ✘ Specialized Grammar <factor F> is ((<expr>)) ✘
  67. 90

  68. def jsoncheck(json): if any_key_has_null_value(json): fail(’key value must not be null’)

    process(json) {"abc": null} ✘ <item N> is <string> : null 92
  69. {"abc": []} ✔ no <item N> is <string> : null

    def jsoncheck(json): if any_key_has_null_value(json): fail(’key value must not be null’) process(json) 93
  70. {"abc": 124} ✘ no <item E> is "" : <elt>

    def jsoncheck(json): if no_key_is_empty_string(json): fail(’one key must be empty’) process(json) 94
  71. def jsoncheck(json): if no_key_is_empty_string(json): fail(’one key must be empty’) if

    any_key_has_null_value(json): fail(’key value must not be null’) process(json) 96
  72. def jsoncheck(json): if no_key_is_empty_string(json): fail(’one key must be empty’) if

    any_key_has_null_value(json): fail(’key value must not be null’) process(json) {"": 124} ✔ <item E> is "" : <elt> no <item N> is <string> : null & 97
  73. def jsoncheck(json): if any_key_has_null_value(json): fail(’key value must not be null’)

    process(json) {"abc": null} ✘ <item N> is <string> : null Start Symbol 98
  74. def jsoncheck(json): if any_key_has_null_value(json): fail(’key value must not be null’)

    process(json) {"abc": []} no <item N> is <string> : null ✔ Start Symbol 99
  75. <item E> is "" : <elt> no <item N> is

    <string> : null & def jsoncheck(json): if no_key_is_empty_string(json): fail(’one key must be empty’) if any_key_has_null_value(json): fail(’key value must not be null’) process(json) {"": 124} ✔ Start Symbol 101
  76. def jsoncheck(json): if no_key_is_empty_string(json): fail(’one key must be empty’) if

    any_key_has_null_value(json): fail(’key value must not be null’) process(json) Evogram Automatically Derived 102
  77. def jsoncheck(json): if no_key_is_empty_string(json): fail(’one key must be empty’) if

    any_key_has_null_value(json): fail(’key value must not be null’) process(json) Automatically Derived 103
  78. Supercharged Pattern Matchers <json E and not(N)> where <item E>

    is "": <elt> <item N> is <string>:null <calc not(D or F)> where <factor F> is ((<expr>)) <term D> is <factor> / 0 <ipv4addr O and H> where <quad O> is "0" <num> <quad H> is "0x" <num> <C not(F) not(EW or ED or F)> where <forCondition F> is ";;" <iterationStatement EW> is <WHILE> "()" <statement> <iterationStatement ED> is <DO> <statement> <WHILE> "()" <eos> Alternative to Regular Expressions 104