Fanbase

ppm/ppm-boundary

version 1.0

Same as ppm, with values taken from the edges of what the format allows (maxval 1, 255, 256 and 65535; leading-zero dimensions; every whitespace flavour)

Format
Portable Pixmap (ppm)
Authors
The Fandango Fuzzer Team
License
Apache-2.0
Fandango
>=1.3
Extensions
ppm
Media type
image/x-portable-pixmap
Specification
http://netpbm.sourceforge.net/doc/ppm.html
Its files should decode
mostly
In the registry
specs/ppm/ppm-boundary/ppm-boundary.fan

Use it

fanbase install ppm-boundary
fandango fuzz -F ppm-boundary -n 10

How it does

accepts 92%, covers 24.6%, 54/s. 1000 inputs, seed 1.

ParserAcceptsVersion
ffmpeg0%ffmpeg version 7.1.5-0+deb13u1
ffmpeg-pnm-cov4%FFmpeg (PNM family, for PPM) 9.0.2
imagemagick1%Version: ImageMagick 7.1.1-43 Q16 x86_64 22550
pillow92%12.3.0

The spec says its files decode mostly: as expected.

ffmpeg-pnm-cov

lines reached
24.6% of 516
real files reach
34.1%
only the generated files
8 lines
only the real files
57 lines
9.5% after 1 inputs, 24.6% after 1000real files: 34.1%

Cite it

@software{fanbase_ppm_ppm_boundary_1_0,
  author  = {{The Fandango Fuzzer Team}},
  title   = {Portable Pixmap (ppm/ppm-boundary), a Fandango input specification},
  version = {1.0},
  url     = {https://github.com/fandango-fuzzer/fanbase},
  note    = {Fanbase registry, specs/ppm/ppm-boundary/ppm-boundary.fan, sha256 80c380ffc714},
}

Source

Source (49 lines)
# Same as ppm, with values taken from the edges of what the format allows:
# maxval 1, 255, 256 and 65535; leading-zero dimensions; comment lines woven
# through the header; every whitespace flavour including VT and FF.

<start> ::= <p6_1> | <p6_255> | <p6_256> | <p6_65535> | <p3_255> | <p3_65535>

<p6_1>     ::= "P6" <sp> <width> <sp> <height> <sp> "1" <sws> <ras8>
<p6_255>   ::= "P6" <sp> <width> <sp> <height> <sp> "255" <sws> <ras8>
<p6_256>   ::= "P6" <sp> <width> <sp> <height> <sp> "256" <sws> <ras16>
<p6_65535> ::= "P6" <sp> <width> <sp> <height> <sp> "65535" <sws> <ras16>
<p3_255>   ::= "P3" <sp> <width> <sp> <height> <sp> "255" <sp> <p3r255>
<p3_65535> ::= "P3" <sp> <width> <sp> <height> <sp> "65535" <sp> <p3r65535>

# Dimensions: minimums and a leading-zero form (Netpbm parses "01" as 1).
<width>  ::= "1" | "2" | "3" | "01"
<height> ::= "1" | "2" | "3" | "01"

# Header whitespace: at least one item; items include comments and VT/FF.
<sp>  ::= <spi> <spi>*
<spi> ::= " " | "\t" | "\n" | "\r" | "\x0b" | "\x0c" | <comment>
<comment> ::= "#" <ctext> "\n"
<ctext>   ::= r'[^\n]*'

# Exactly ONE whitespace char ends MAXVAL before a P6 raster.
<sws> ::= " " | "\t" | "\n" | "\r"

# P6 raster bytes (comment/whitespace-free binary blob).
<ras8>  ::= <b>+
<ras16> ::= <b>+
<b> ::= rb'[\x00-\xff]'

# P3 raster: numeric samples with whitespace separators (no comments here so
# the token count stays exact). s255 regex is bounded to 0..255.
<p3r255>   ::= <s255r>
<s255r>    ::= <s255> <nws> <s255r> | <s255> <nws>
<s255>     ::= r'([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
<p3r65535> ::= <s16r>
<s16r>     ::= <s16> <nws> <s16r> | <s16> <nws>
<s16>      ::= r'[0-9]{1,5}'
<nws> ::= " " | "\t" | "\n" | "\r\n"

# cross-field constraints
# P6: emitted byte length == WIDTH*HEIGHT*3*bytes_per_sample.
where len(bytes(<ras8>))  == int(str(<width>)) * int(str(<height>)) * 3
where len(bytes(<ras16>)) == int(str(<width>)) * int(str(<height>)) * 3 * 2
# P3: numeric-token count == WIDTH*HEIGHT*3, and every sample <= MAXVAL.
where len(str(<p3r255>).split())   == int(str(<width>)) * int(str(<height>)) * 3
where len(str(<p3r65535>).split()) == int(str(<width>)) * int(str(<height>)) * 3
where all(int(t) <= 65535 for t in str(<p3r65535>).split())