mirror of https://bitbucket.org/ausocean/av.git
Merged in level-prefix-fuzz (pull request #256)
codec/h264/h264dec/fuzz: added fuzzer test for parseLevelPrefix function Approved-by: Saxon Milton <saxon.milton@gmail.com>
This commit is contained in:
commit
615ec66163
|
@ -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,72 @@
|
||||||
|
/*
|
||||||
|
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)))
|
||||||
|
if cbr == nil {
|
||||||
|
panic("new_BitReader returned NULL pointer")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
want := C.read_levelprefix(cbr)
|
||||||
|
if want < 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.
|
||||||
|
got, 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(got) != int(want) {
|
||||||
|
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,78 @@
|
||||||
|
/*
|
||||||
|
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));
|
||||||
|
if(r == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
r->data = d;
|
||||||
|
r->curr = 0;
|
||||||
|
r->len = l;
|
||||||
|
r->err = 0;
|
||||||
|
|
||||||
|
BitReader* br = (BitReader*)malloc(sizeof(BitReader));
|
||||||
|
if(br == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
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