Live data from Hacker News

The Day I Fell in Love with Fuzzing

nullprogram.com

41–49 of 49 posts

Re: The Day I Fell in Love with Fuzzing

#41
post #17

I haven't tried afl-fuzz myself, although it sounds like world-class awesome software, but I'm a real believer in testing things with David MacIver's Hypothesis, which invokes your functions with random inputs, and then does similar canonicalization and minimization kinds of things. I like Hypothesis so much that when I wrote Dumpulse http://github.com/kragen/dumpulse I added a Python interface to it purely so I coul…

I love the concept of hypothesis, but I struggle with finding a real life use case. I just can't formulate my assertions, I don't know what to put in them. unit tests are easy since I know what the code does, and I can just tell it what to do and what I expect. But with hypothesis, I have to find some kind of general property, which I have a hard time to do. Any tips, or materials I can use ? P.S: I read your test.py…

Well, normally Hypothesis just calls a function with some random arguments and checks that it "works", operationalized as "doesn't crash". But that's inadequate for testing stateful APIs, in which calling a single function isn't useful — for stateful APIs, you need to go through a series of calls, not just a single call. So the rule-based state machine thing gives you a way to describe the valid series of calls, and Hypothesis then generates 100 random sequences according to your spec and verifies that they all work. David wrote the article about it in 2017 that felixyz already linked: https://hypothesis.works/articles/rule-based-stateful-testin...

In many cases, though, it's better if you can refactor your code to support a stateless interface, and then you can write simple single-step function tests.

How do you know what to test? There's a whole spectrum. Just testing that valid inputs don't crash is often pretty useful. (If you're not sure what valid inputs would be, maybe try writing the README before the tests.) In the case of Dumpulse, I went to the other extreme; its actual semantics are extremely dumb (thus the name), so the test suite includes a reimplementation in Python of the intended semantics, and the test verifies that the implementation in C has the same behavior. (But in constant space and strictly limited runtime, which the Hypothesis test doesn't check.)

I picked a few functions and classes at random to see what kind of testable properties I could find:

- sympy.polys.rationaltools.together: this function gives a testable assertion in its docstring: "``apart(together(expr))`` should return expr unchanged." That's an easy property to test. Also, though, its output expression is intended to be equivalent to its input expression, so if you put together some kind of generator of expressions (which is actually the hard part in this context), you could verify that together(expr) always evaluates to the numerically same value as expr.

- horizons.world.buildability.settlementcache.SettlementBuildabilityCache: this seems to be a storage system that caches some data and then incrementally updates the cache as the data is modified. The desired property seems to be that adding some data to the cache, then modifying it, gives you the same results as you would have gotten just by adding the modified data to an empty cache. Also I think there's a serialization aspect, so you could check to see if loading the cache from a binary blob gives you the same results as just creating it in memory.

- statsmodels.datasets.macrodata.data.load: this function loads a CSV file from disk. Really all you can test about it, without interposition at the filesystem layer, is that it returns some data. It doesn't really take any inputs. A lot of installation problems could cause it to throw an error, though, so that would be a useful test in some circumstances.

- sre_constants: if executed as a script, this program should generate a syntactically valid .h file in sre_constants.h. You should be able to feed that to a C compiler to verify that, but if you care about that, your build system is probably already doing it!

Do you want to point me at some code of yours so I can see what kind of useful property-based tests could be written for it?

Re: The Day I Fell in Love with Fuzzing

#43
post #41

Earlier quoted context omitted.

I love the concept of hypothesis, but I struggle with finding a real life use case. I just can't formulate my assertions, I don't know what to put in them. unit tests are easy since I know what the code does, and I can just tell it what to do and what I expect. But with hypothesis, I have to find some kind of general property, which I have a hard time to do. Any tips, or materials I can use ? P.S: I read your test.py…

Well, normally Hypothesis just calls a function with some random arguments and checks that it "works", operationalized as "doesn't crash". But that's inadequate for testing stateful APIs, in which calling a single function isn't useful — for stateful APIs, you need to go through a series of calls, not just a single call. So the rule-based state machine thing gives you a way to describe the valid series of calls, and…

Thank you. Yes, please give me an example on a few functions from: https://github.com/Tygs/ayo/blob/master/ayo/scope.py

Re: The Day I Fell in Love with Fuzzing

#44
> I also combed through the outputs to see what sorts of inputs were succeeding, what was failing, and observe how my program handled various edge cases. It was rejecting some inputs I thought should be valid, accepting some I thought should be invalid, and interpreting some in ways I hadn’t intended. So even after I fixed the crashing inputs, I still made tweaks to the parser to fix each of these troublesome inputs.

I love just looking through the absurd stuff AFL comes up with, even if it's not causing a crash or incorrect behavior. Like this bit of art it caused my parser generator to produce: https://i.imgur.com/VoV7cU9.png

Re: The Day I Fell in Love with Fuzzing

#46
post #24

Earlier quoted context omitted.

I love the concept of hypothesis, but I struggle with finding a real life use case. I just can't formulate my assertions, I don't know what to put in them. unit tests are easy since I know what the code does, and I can just tell it what to do and what I expect. But with hypothesis, I have to find some kind of general property, which I have a hard time to do. Any tips, or materials I can use ? P.S: I read your test.py…

You might find these useful: https://hypothesis.works/articles/rule-based-stateful-testin... http://propertesting.com/book_stateful_properties.html For a long time, I felt the same way you describe: all introductions to property-based testing show you things like testing a function that reverses a list and yes it all looks very useful and nifty, but it's hard to imagine how to formulate interesting variants for more…

fred hebert (monocqc) has his actual book out just now on Amazon, iirc

https://www.amazon.com/gp/product/1680506218

Re: The Day I Fell in Love with Fuzzing

#48
post #6

> When I got started, I had just learned how to use yacc (really Bison) and lex (really flex) I've dug into parsers a few times, but everything I encountered seemed to think that once I had a parsed tree of commands it was obvious how to consume it...and it wasn't (for me). I've never had the free time to dedicate to experimenting that abstractly, so anytime I'm tempted to write a DSL or similar for a current problem…

PEGs (parsing expression grammars) are probably the by far easiest way currently.

Re: The Day I Fell in Love with Fuzzing

#49
post #38
post #11

Earlier quoted context omitted.

IMHO you're often best off with writing a simple recursive descent parser by hand. For lexing you can often get away with splitting the input string at word boundaries. For slightly more advanced needs, parser combinator libraries make parsing and lexing quite straightforward. I honestly wouldn't use a parser generator.

Regular expressions are also useful for lexing. I like to work from this example code from the Python standard library docs: https://docs.python.org/3.6/library/re.html#writing-a-tokeni...

Remember, `lex` is just a pile of regular expressions, so it is great for simple parsing in C. There are good reasons it was known as the Swiss Army knife of Unix before scripting took over :-)
Post reply on HN