mirror of https://bitbucket.org/ausocean/av.git
codec/h264/h264dec/fuzz: added fuzzer test for parseLevelPrefix function
The fuzz package has been created, which will house C based helper code and sub-packages dedicated to each fuzz test. A sub packaged called fuzzParseLevelPrefix has been created to house the fuzz test for parseLevelPrefix. Emeric's C code has been isolated into some C files, and a file called fuzz.go has been created, which houses the actual fuzz test function. An initial corpus has been added with 3 inputs.
This commit is contained in:
parent
f8f78947f9
commit
faf5e2df0f
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
DESCRIPTION
|
||||
cavlc_fuzz.go provides exported wrappers for unexported CAVLC functions such
|
||||
that the fuzz package can access these functions for testing.
|
||||
|
||||
AUTHORS
|
||||
Saxon A. Nelson-Milton <saxon@ausocean.org>
|
||||
|
||||
LICENSE
|
||||
Copyright (C) 2019 the Australian Ocean Lab (AusOcean).
|
||||
|
||||
It is free software: you can redistribute it and/or modify them
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation, either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
in gpl.txt. If not, see http://www.gnu.org/licenses.
|
||||
*/
|
||||
|
||||
package h264dec
|
||||
|
||||
import "bitbucket.org/ausocean/av/codec/h264/h264dec/bits"
|
||||
|
||||
func FuzzParseLevelPrefix(br *bits.BitReader) (int, error) {
|
||||
return parseLevelPrefix(br)
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1 @@
|
|||
01
|
|
@ -0,0 +1 @@
|
|||
001
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
DESCRIPTION
|
||||
fuzz.go provides a function with the required signature such that it may be
|
||||
accessed by go-fuzz. The function will compare the output of C level_prefix
|
||||
parser with a go version.
|
||||
|
||||
AUTHORS
|
||||
Saxon A. Nelson-Milton <saxon@ausocean.org>
|
||||
|
||||
LICENSE
|
||||
Copyright (C) 2019 the Australian Ocean Lab (AusOcean).
|
||||
|
||||
It is free software: you can redistribute it and/or modify them
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation, either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
in gpl.txt. If not, see http://www.gnu.org/licenses.
|
||||
*/
|
||||
|
||||
// +build gofuzz
|
||||
|
||||
package fuzzParseLevelPrefix
|
||||
|
||||
/*
|
||||
#include "../helpers.c"
|
||||
#include "parse_level_prefix.h"
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"bitbucket.org/ausocean/av/codec/h264/h264dec"
|
||||
"bitbucket.org/ausocean/av/codec/h264/h264dec/bits"
|
||||
)
|
||||
|
||||
func Fuzz(data []byte) int {
|
||||
// Create C based BitReader based on data.
|
||||
cbr := C.new_BitReader((*C.char)(unsafe.Pointer(&data[0])), C.int(len(data)))
|
||||
|
||||
// Get the level_prefix from the C code. If got is < 0, then the C code
|
||||
// doesn't like it and we shouldn't have that input in the corpus, so return -1.
|
||||
got := C.read_levelprefix(cbr)
|
||||
if got < 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
// Get the level_prefix from the go code. If the C code was okay with this
|
||||
// input, but the go code isn't then that's bad, so panic - want crasher info.
|
||||
want, err := h264dec.FuzzParseLevelPrefix(bits.NewBitReader(bytes.NewReader(data)))
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("error from go parseLevelPrefix: %v", err))
|
||||
}
|
||||
|
||||
// Compare the result of the C and go code. If they are not the same then
|
||||
// panic - our go code is not doing what it should.
|
||||
if int(want) != int(got) {
|
||||
panic(fmt.Sprintf("did not get expected results for input: %v\nGot: %v\nWant: %v\n", data, got, want))
|
||||
}
|
||||
return 1
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
DESCRIPTION
|
||||
parse_level_prefix.c contains a function that will parse the level_prefix
|
||||
when performaing CAVLC decoding; extracted from Emeric Grange's h264 decoder
|
||||
contained in MiniVideo (https://github.com/emericg/MiniVideo). This is used
|
||||
to generate input and output data for testing purposes.
|
||||
|
||||
AUTHORS
|
||||
Emeric Grange <emeric.grange@gmail.com>
|
||||
Saxon A. Nelson-Milton <saxon@ausocean.org>
|
||||
|
||||
LICENSE
|
||||
COPYRIGHT (C) 2018 Emeric Grange - All Rights Reserved
|
||||
|
||||
This file is part of MiniVideo.
|
||||
|
||||
MiniVideo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MiniVideo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with MiniVideo. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "parse_level_prefix.h"
|
||||
#include "../helpers.h"
|
||||
|
||||
/*!
|
||||
* \brief Parsing process for level_prefix.
|
||||
* \param *dc The current DecodingContext.
|
||||
* \return leadingZeroBits.
|
||||
*
|
||||
* From 'ITU-T H.264' recommendation:
|
||||
* 9.2.2.1 Parsing process for level_prefix
|
||||
*
|
||||
* The parsing process for this syntax element consists in reading the bits
|
||||
* starting at the current location in the bitstream up to and including the
|
||||
* first non-zero bit, and counting the number of leading bits that are equal to 0.
|
||||
*
|
||||
* level_prefix and level_suffix specify the value of a non-zero transform coefficient level.
|
||||
* The range of level_prefix and level_suffix is specified in subclause 9.2.2.
|
||||
*/
|
||||
int read_levelprefix(struct BitReader *br){
|
||||
int leadingZeroBits = -1;
|
||||
int b = 0;
|
||||
for (b = 0; !b; leadingZeroBits++){
|
||||
b = read_bits(br,1);
|
||||
if( br->err != 0 ){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return leadingZeroBits;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef PARSE_LEVEL_PREFIX_H
|
||||
#define PARSE_LEVEL_PREFIX_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../helpers.h"
|
||||
|
||||
int read_levelprefix(struct BitReader *br);
|
||||
|
||||
#endif // PARSE_LEVEL_PREFIX_H
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
DESCRIPTION
|
||||
helpers.c provides C helper functions for interfacing with C code used for
|
||||
testing in this package.
|
||||
|
||||
AUTHORS
|
||||
Saxon A. Nelson-Milton <saxon@ausocean.org>
|
||||
|
||||
LICENSE
|
||||
Copyright (C) 2019 the Australian Ocean Lab (AusOcean).
|
||||
|
||||
It is free software: you can redistribute it and/or modify them
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation, either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
in gpl.txt. If not, see http://www.gnu.org/licenses.
|
||||
*/
|
||||
|
||||
#include "helpers.h"
|
||||
|
||||
typedef struct BitReader BitReader;
|
||||
typedef struct Reader Reader;
|
||||
|
||||
BitReader* new_BitReader(char* d, int l){
|
||||
Reader* r = (Reader*)malloc(sizeof(Reader));
|
||||
r->data = d;
|
||||
r->curr = 0;
|
||||
r->len = l;
|
||||
r->err = 0;
|
||||
|
||||
BitReader* br = (BitReader*)malloc(sizeof(BitReader));
|
||||
br->r = r;
|
||||
br->n = 0;
|
||||
br->bits = 0;
|
||||
br->nRead = 0;
|
||||
br->err = 0;
|
||||
return br;
|
||||
}
|
||||
|
||||
char next_byte(Reader *r) {
|
||||
if(r->curr >= r->len){
|
||||
r->err = 1;
|
||||
}
|
||||
char next = r->data[r->curr];
|
||||
r->curr++;
|
||||
return next;
|
||||
}
|
||||
|
||||
uint64_t read_bits(BitReader *br, int n) {
|
||||
while( n > br->bits ){
|
||||
char b = next_byte(br->r);
|
||||
if(br->r->err != 0){
|
||||
br->err = 1;
|
||||
return 0;
|
||||
}
|
||||
br->nRead++;
|
||||
br->n <<= 8;
|
||||
br->n |= (uint64_t)b;
|
||||
br->bits += 8;
|
||||
}
|
||||
|
||||
uint64_t r = (br->n >> (br->bits-n)) & ((1 << n) - 1);
|
||||
br->bits -= n;
|
||||
return r;
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
DESCRIPTION
|
||||
helpers.h defines some structs and function signatures that will help to
|
||||
interface with C code used in our fuzz testing.
|
||||
|
||||
AUTHORS
|
||||
Saxon A. Nelson-Milton <saxon@ausocean.org>
|
||||
|
||||
LICENSE
|
||||
Copyright (C) 2019 the Australian Ocean Lab (AusOcean).
|
||||
|
||||
It is free software: you can redistribute it and/or modify them
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation, either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
in gpl.txt. If not, see http://www.gnu.org/licenses.
|
||||
*/
|
||||
|
||||
#ifndef HELPERS_H
|
||||
#define HELPERS_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct Reader {
|
||||
char* data;
|
||||
int curr;
|
||||
int len;
|
||||
int err;
|
||||
};
|
||||
|
||||
struct BitReader {
|
||||
struct Reader* r;
|
||||
uint64_t n;
|
||||
int bits;
|
||||
int nRead;
|
||||
int err;
|
||||
};
|
||||
|
||||
// new_BitReader returns a new instance of a BitReader given the backing array
|
||||
// d and the length of the data l.
|
||||
struct BitReader* new_BitReader(char*, int);
|
||||
|
||||
// next_byte provides the next byte from a Reader r and advances it's byte index.
|
||||
char next_byte(struct Reader*);
|
||||
|
||||
// read_bits intends to emulate the BitReader.ReadBits function defined in the
|
||||
// bits package. This is used when a bit reader is required to obtain bytes from
|
||||
// a stream in the C test code.
|
||||
uint64_t read_bits(struct BitReader*, int);
|
||||
|
||||
#endif // HELPERS_H
|
Loading…
Reference in New Issue