From: Michael Brown Date: Tue, 22 Apr 2025 11:13:22 +0000 (+0100) Subject: [deflate] Remove userptr_t from decompression code X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=c059b341707863f8ecc4ecde75dd608dda72fdad;p=thirdparty%2Fipxe.git [deflate] Remove userptr_t from decompression code Simplify the deflate, zlib, and gzip decompression code by assuming that all content is fully accessible via pointer dereferences. Signed-off-by: Michael Brown --- diff --git a/src/crypto/deflate.c b/src/crypto/deflate.c index c6cce7516..5d0101184 100644 --- a/src/crypto/deflate.c +++ b/src/crypto/deflate.c @@ -28,7 +28,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include #include -#include #include /** @file @@ -300,24 +299,21 @@ static int deflate_alphabet ( struct deflate *deflate, * Attempt to accumulate bits from input stream * * @v deflate Decompressor - * @v in Compressed input data * @v target Number of bits to accumulate * @ret excess Number of excess bits accumulated (may be negative) */ static int deflate_accumulate ( struct deflate *deflate, - struct deflate_chunk *in, unsigned int target ) { uint8_t byte; while ( deflate->bits < target ) { /* Check for end of input */ - if ( in->offset >= in->len ) + if ( deflate->in == deflate->end ) break; /* Acquire byte from input */ - copy_from_user ( &byte, in->data, in->offset++, - sizeof ( byte ) ); + byte = *(deflate->in++); deflate->accumulator = ( deflate->accumulator | ( byte << deflate->bits ) ); deflate->rotalumucca = ( deflate->rotalumucca | @@ -359,12 +355,10 @@ static int deflate_consume ( struct deflate *deflate, unsigned int count ) { * Attempt to extract a fixed number of bits from input stream * * @v deflate Decompressor - * @v in Compressed input data * @v target Number of bits to extract * @ret data Extracted bits (or negative if not yet accumulated) */ -static int deflate_extract ( struct deflate *deflate, struct deflate_chunk *in, - unsigned int target ) { +static int deflate_extract ( struct deflate *deflate, unsigned int target ) { int excess; int data; @@ -373,7 +367,7 @@ static int deflate_extract ( struct deflate *deflate, struct deflate_chunk *in, return 0; /* Attempt to accumulate bits */ - excess = deflate_accumulate ( deflate, in, target ); + excess = deflate_accumulate ( deflate, target ); if ( excess < 0 ) return excess; @@ -389,12 +383,10 @@ static int deflate_extract ( struct deflate *deflate, struct deflate_chunk *in, * Attempt to decode a Huffman-coded symbol from input stream * * @v deflate Decompressor - * @v in Compressed input data * @v alphabet Huffman alphabet * @ret code Raw code (or negative if not yet accumulated) */ static int deflate_decode ( struct deflate *deflate, - struct deflate_chunk *in, struct deflate_alphabet *alphabet ) { struct deflate_huf_symbols *huf_sym; uint16_t huf; @@ -407,7 +399,7 @@ static int deflate_decode ( struct deflate *deflate, * even if the stream still contains some complete * Huffman-coded symbols. */ - deflate_accumulate ( deflate, in, DEFLATE_HUFFMAN_BITS ); + deflate_accumulate ( deflate, DEFLATE_HUFFMAN_BITS ); /* Normalise the bit-reversed accumulated value to 16 bits */ huf = ( deflate->rotalumucca >> 16 ); @@ -449,24 +441,22 @@ static void deflate_discard_to_byte ( struct deflate *deflate ) { * Copy data to output buffer (if available) * * @v out Output data buffer - * @v start Source data - * @v offset Starting offset within source data + * @v in Input data * @v len Length to copy */ -static void deflate_copy ( struct deflate_chunk *out, - userptr_t start, size_t offset, size_t len ) { - size_t out_offset = out->offset; +static void deflate_copy ( struct deflate_chunk *out, const void *in, + size_t len ) { + const uint8_t *in_byte = in; + uint8_t *out_byte = ( out->data + out->offset ); size_t copy_len; /* Copy data one byte at a time, to allow for overlap */ - if ( out_offset < out->len ) { - copy_len = ( out->len - out_offset ); + if ( out->offset < out->len ) { + copy_len = ( out->len - out->offset ); if ( copy_len > len ) copy_len = len; - while ( copy_len-- ) { - memcpy ( ( out->data + out_offset++ ), - ( start + offset++ ), 1 ); - } + while ( copy_len-- ) + *(out_byte++) = *(in_byte++); } out->offset += len; } @@ -475,7 +465,8 @@ static void deflate_copy ( struct deflate_chunk *out, * Inflate compressed data * * @v deflate Decompressor - * @v in Compressed input data + * @v data Compressed input data + * @v len Length of compressed input data * @v out Output data buffer * @ret rc Return status code * @@ -489,10 +480,13 @@ static void deflate_copy ( struct deflate_chunk *out, * caller can use this to find the length of the decompressed data * before allocating the output data buffer. */ -int deflate_inflate ( struct deflate *deflate, - struct deflate_chunk *in, +int deflate_inflate ( struct deflate *deflate, const void *data, size_t len, struct deflate_chunk *out ) { + /* Store input data pointers */ + deflate->in = data; + deflate->end = ( data + len ); + /* This could be implemented more neatly if gcc offered a * means for enforcing tail recursion. */ @@ -509,7 +503,7 @@ int deflate_inflate ( struct deflate *deflate, int cm; /* Extract header */ - header = deflate_extract ( deflate, in, ZLIB_HEADER_BITS ); + header = deflate_extract ( deflate, ZLIB_HEADER_BITS ); if ( header < 0 ) { deflate->resume = &&zlib_header; return 0; @@ -538,7 +532,7 @@ int deflate_inflate ( struct deflate *deflate, int btype; /* Extract block header */ - header = deflate_extract ( deflate, in, DEFLATE_HEADER_BITS ); + header = deflate_extract ( deflate, DEFLATE_HEADER_BITS ); if ( header < 0 ) { deflate->resume = &&block_header; return 0; @@ -571,17 +565,17 @@ int deflate_inflate ( struct deflate *deflate, } literal_len: { - int len; + int llen; /* Extract LEN field */ - len = deflate_extract ( deflate, in, DEFLATE_LITERAL_LEN_BITS ); - if ( len < 0 ) { + llen = deflate_extract ( deflate, DEFLATE_LITERAL_LEN_BITS ); + if ( llen < 0 ) { deflate->resume = &&literal_len; return 0; } /* Record length of literal data */ - deflate->remaining = len; + deflate->remaining = llen; DBGC2 ( deflate, "DEFLATE %p literal block length %#04zx\n", deflate, deflate->remaining ); } @@ -590,7 +584,7 @@ int deflate_inflate ( struct deflate *deflate, int nlen; /* Extract NLEN field */ - nlen = deflate_extract ( deflate, in, DEFLATE_LITERAL_LEN_BITS); + nlen = deflate_extract ( deflate, DEFLATE_LITERAL_LEN_BITS ); if ( nlen < 0 ) { deflate->resume = &&literal_nlen; return 0; @@ -608,20 +602,20 @@ int deflate_inflate ( struct deflate *deflate, literal_data: { size_t in_remaining; - size_t len; + size_t dlen; /* Calculate available amount of literal data */ - in_remaining = ( in->len - in->offset ); - len = deflate->remaining; - if ( len > in_remaining ) - len = in_remaining; + in_remaining = ( deflate->end - deflate->in ); + dlen = deflate->remaining; + if ( dlen > in_remaining ) + dlen = in_remaining; /* Copy data to output buffer */ - deflate_copy ( out, in->data, in->offset, len ); + deflate_copy ( out, deflate->in, dlen ); /* Consume data from input buffer */ - in->offset += len; - deflate->remaining -= len; + deflate->in += dlen; + deflate->remaining -= dlen; /* Finish processing if we are blocked */ if ( deflate->remaining ) { @@ -657,7 +651,7 @@ int deflate_inflate ( struct deflate *deflate, unsigned int hclen; /* Extract block header */ - header = deflate_extract ( deflate, in, DEFLATE_DYNAMIC_BITS ); + header = deflate_extract ( deflate, DEFLATE_DYNAMIC_BITS ); if ( header < 0 ) { deflate->resume = &&dynamic_header; return 0; @@ -684,7 +678,7 @@ int deflate_inflate ( struct deflate *deflate, } dynamic_codelen: { - int len; + int clen; unsigned int index; int rc; @@ -692,18 +686,18 @@ int deflate_inflate ( struct deflate *deflate, while ( deflate->length_index < deflate->length_target ) { /* Extract code length length */ - len = deflate_extract ( deflate, in, - DEFLATE_CODELEN_BITS ); - if ( len < 0 ) { + clen = deflate_extract ( deflate, + DEFLATE_CODELEN_BITS ); + if ( clen < 0 ) { deflate->resume = &&dynamic_codelen; return 0; } /* Store code length */ index = deflate_codelen_map[deflate->length_index++]; - deflate_set_length ( deflate, index, len ); + deflate_set_length ( deflate, index, clen ); DBGCP ( deflate, "DEFLATE %p codelen for %d is %d\n", - deflate, index, len ); + deflate, index, clen ); } /* Generate code length alphabet */ @@ -722,25 +716,25 @@ int deflate_inflate ( struct deflate *deflate, } dynamic_litlen_distance: { - int len; + int clen; int index; /* Decode literal/length/distance code length */ - len = deflate_decode ( deflate, in, &deflate->distance_codelen); - if ( len < 0 ) { + clen = deflate_decode ( deflate, &deflate->distance_codelen ); + if ( clen < 0 ) { deflate->resume = &&dynamic_litlen_distance; return 0; } /* Prepare for extra bits */ - if ( len < 16 ) { - deflate->length = len; + if ( clen < 16 ) { + deflate->length = clen; deflate->extra_bits = 0; deflate->dup_len = 1; } else { static const uint8_t dup_len[3] = { 3, 3, 11 }; static const uint8_t extra_bits[3] = { 2, 3, 7 }; - index = ( len - 16 ); + index = ( clen - 16 ); deflate->dup_len = dup_len[index]; deflate->extra_bits = extra_bits[index]; if ( index ) @@ -753,7 +747,7 @@ int deflate_inflate ( struct deflate *deflate, unsigned int dup_len; /* Extract extra bits */ - extra = deflate_extract ( deflate, in, deflate->extra_bits ); + extra = deflate_extract ( deflate, deflate->extra_bits ); if ( extra < 0 ) { deflate->resume = &&dynamic_litlen_distance_extra; return 0; @@ -830,7 +824,7 @@ int deflate_inflate ( struct deflate *deflate, while ( 1 ) { /* Decode Huffman code */ - code = deflate_decode ( deflate, in, &deflate->litlen ); + code = deflate_decode ( deflate, &deflate->litlen ); if ( code < 0 ) { deflate->resume = &&lzhuf_litlen; return 0; @@ -844,8 +838,7 @@ int deflate_inflate ( struct deflate *deflate, DBGCP ( deflate, "DEFLATE %p literal %#02x " "('%c')\n", deflate, byte, ( isprint ( byte ) ? byte : '.' ) ); - deflate_copy ( out, virt_to_user ( &byte ), 0, - sizeof ( byte ) ); + deflate_copy ( out, &byte, sizeof ( byte ) ); } else if ( code == DEFLATE_LITLEN_END ) { @@ -876,7 +869,7 @@ int deflate_inflate ( struct deflate *deflate, int extra; /* Extract extra bits */ - extra = deflate_extract ( deflate, in, deflate->extra_bits ); + extra = deflate_extract ( deflate, deflate->extra_bits ); if ( extra < 0 ) { deflate->resume = &&lzhuf_litlen_extra; return 0; @@ -892,8 +885,7 @@ int deflate_inflate ( struct deflate *deflate, unsigned int bits; /* Decode Huffman code */ - code = deflate_decode ( deflate, in, - &deflate->distance_codelen ); + code = deflate_decode ( deflate, &deflate->distance_codelen ); if ( code < 0 ) { deflate->resume = &&lzhuf_distance; return 0; @@ -914,7 +906,7 @@ int deflate_inflate ( struct deflate *deflate, size_t dup_distance; /* Extract extra bits */ - extra = deflate_extract ( deflate, in, deflate->extra_bits ); + extra = deflate_extract ( deflate, deflate->extra_bits ); if ( extra < 0 ) { deflate->resume = &&lzhuf_distance_extra; return 0; @@ -934,7 +926,7 @@ int deflate_inflate ( struct deflate *deflate, } /* Copy data, allowing for overlap */ - deflate_copy ( out, out->data, ( out->offset - dup_distance ), + deflate_copy ( out, ( out->data + out->offset - dup_distance ), dup_len ); /* Process next literal/length symbol */ @@ -972,7 +964,7 @@ int deflate_inflate ( struct deflate *deflate, * cases involved in calling deflate_extract() to * obtain a full 32 bits. */ - excess = deflate_accumulate ( deflate, in, ZLIB_ADLER32_BITS ); + excess = deflate_accumulate ( deflate, ZLIB_ADLER32_BITS ); if ( excess < 0 ) { deflate->resume = &&zlib_adler32; return 0; diff --git a/src/image/gzip.c b/src/image/gzip.c index 116d912d7..b72c3243e 100644 --- a/src/image/gzip.c +++ b/src/image/gzip.c @@ -24,10 +24,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include +#include #include #include #include -#include #include #include #include @@ -46,83 +46,92 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * @ret rc Return status code */ static int gzip_extract ( struct image *image, struct image *extracted ) { - struct gzip_header header; - struct gzip_extra_header extra; - struct gzip_crc_header crc; - struct gzip_footer footer; - struct deflate_chunk in; - unsigned int strings; - size_t offset; + const struct gzip_header *header; + const struct gzip_extra_header *extra; + const struct gzip_crc_header *crc; + const struct gzip_footer *footer; + const void *data; + size_t extra_len; + size_t string_len; size_t len; - off_t nul; + unsigned int strings; int rc; /* Sanity check */ - assert ( image->len >= ( sizeof ( header ) + sizeof ( footer ) ) ); + assert ( image->len >= ( sizeof ( *header ) + sizeof ( *footer ) ) ); + data = image->data; + len = image->len; /* Extract footer */ - len = ( image->len - sizeof ( footer ) ); - copy_from_user ( &footer, image->data, len, sizeof ( footer ) ); + assert ( len >= sizeof ( *footer ) ); + len -= sizeof ( *footer ); + footer = ( data + len ); /* Extract fixed header */ - copy_from_user ( &header, image->data, 0, sizeof ( header ) ); - offset = sizeof ( header ); - assert ( offset <= ( image->len - sizeof ( footer ) ) ); + assert ( len >= sizeof ( *header ) ); + header = data; + data += sizeof ( *header ); + len -= sizeof ( *header ); /* Skip extra header, if present */ - if ( header.flags & GZIP_FL_EXTRA ) { - copy_from_user ( &extra, image->data, offset, - sizeof ( extra ) ); - offset += sizeof ( extra ); - offset += le16_to_cpu ( extra.len ); - if ( offset > len ) { + if ( header->flags & GZIP_FL_EXTRA ) { + if ( len < sizeof ( *extra ) ) { DBGC ( image, "GZIP %p overlength extra header\n", image ); return -EINVAL; } + extra = data; + data += sizeof ( *extra ); + len -= sizeof ( *extra ); + extra_len = le16_to_cpu ( extra->len ); + if ( len < extra_len ) { + DBGC ( image, "GZIP %p overlength extra header\n", + image ); + return -EINVAL; + } + data += extra_len; + len -= extra_len; } - assert ( offset <= ( image->len - sizeof ( footer ) ) ); /* Skip name and/or comment, if present */ strings = 0; - if ( header.flags & GZIP_FL_NAME ) + if ( header->flags & GZIP_FL_NAME ) strings++; - if ( header.flags & GZIP_FL_COMMENT ) + if ( header->flags & GZIP_FL_COMMENT ) strings++; while ( strings-- ) { - nul = memchr_user ( image->data, offset, 0, ( len - offset ) ); - if ( nul < 0 ) { + string_len = strnlen ( data, len ); + if ( string_len == len ) { DBGC ( image, "GZIP %p overlength name/comment\n", image ); return -EINVAL; } - offset = ( nul + 1 /* NUL */ ); + data += ( string_len + 1 /* NUL */ ); + len -= ( string_len + 1 /* NUL */ ); } - assert ( offset <= ( image->len - sizeof ( footer ) ) ); /* Skip CRC, if present */ - if ( header.flags & GZIP_FL_HCRC ) { - offset += sizeof ( crc ); - if ( offset > len ) { + if ( header->flags & GZIP_FL_HCRC ) { + if ( len < sizeof ( *crc ) ) { DBGC ( image, "GZIP %p overlength CRC header\n", image ); return -EINVAL; } + data += sizeof ( *crc ); + len -= sizeof ( *crc ); } - /* Initialise input chunk */ - deflate_chunk_init ( &in, ( image->data + offset ), 0, len ); - /* Presize extracted image */ if ( ( rc = image_set_len ( extracted, - le32_to_cpu ( footer.len ) ) ) != 0 ) { + le32_to_cpu ( footer->len ) ) ) != 0 ) { DBGC ( image, "GZIP %p could not presize: %s\n", image, strerror ( rc ) ); return rc; } /* Decompress image (expanding if necessary) */ - if ( ( rc = zlib_deflate ( DEFLATE_RAW, &in, extracted ) ) != 0 ) { + if ( ( rc = zlib_deflate ( DEFLATE_RAW, data, len, + extracted ) ) != 0 ) { DBGC ( image, "GZIP %p could not decompress: %s\n", image, strerror ( rc ) ); return rc; @@ -138,19 +147,18 @@ static int gzip_extract ( struct image *image, struct image *extracted ) { * @ret rc Return status code */ static int gzip_probe ( struct image *image ) { - struct gzip_header header; - struct gzip_footer footer; + const struct gzip_header *header; + const struct gzip_footer *footer; /* Sanity check */ - if ( image->len < ( sizeof ( header ) + sizeof ( footer ) ) ) { + if ( image->len < ( sizeof ( *header ) + sizeof ( *footer ) ) ) { DBGC ( image, "GZIP %p image too short\n", image ); return -ENOEXEC; } + header = image->data; /* Check magic header */ - copy_from_user ( &header.magic, image->data, 0, - sizeof ( header.magic ) ); - if ( header.magic != cpu_to_be16 ( GZIP_MAGIC ) ) { + if ( header->magic != cpu_to_be16 ( GZIP_MAGIC ) ) { DBGC ( image, "GZIP %p invalid magic\n", image ); return -ENOEXEC; } diff --git a/src/image/png.c b/src/image/png.c index d5cf7fd8f..8b432e01a 100644 --- a/src/image/png.c +++ b/src/image/png.c @@ -336,13 +336,12 @@ static int png_palette ( struct image *image, struct png_context *png, */ static int png_image_data ( struct image *image, struct png_context *png, size_t len ) { - struct deflate_chunk in; int rc; /* Deflate this chunk */ - deflate_chunk_init ( &in, image->data, png->offset, - ( png->offset + len ) ); - if ( ( rc = deflate_inflate ( &png->deflate, &in, &png->raw ) ) != 0 ) { + if ( ( rc = deflate_inflate ( &png->deflate, + ( image->data + png->offset ), + len, &png->raw ) ) != 0 ) { DBGC ( image, "PNG %s could not decompress: %s\n", image->name, strerror ( rc ) ); return rc; diff --git a/src/image/zlib.c b/src/image/zlib.c index a42c47e1b..d7deee88b 100644 --- a/src/image/zlib.c +++ b/src/image/zlib.c @@ -27,7 +27,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include #include -#include #include #include @@ -41,11 +40,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * Extract compressed data to image * * @v format Compression format code - * @v in Compressed input chunk + * @v data Compressed input data + * @v len Length of compressed input data * @v extracted Extracted image * @ret rc Return status code */ -int zlib_deflate ( enum deflate_format format, struct deflate_chunk *in, +int zlib_deflate ( enum deflate_format format, const void *data, size_t len, struct image *extracted ) { struct deflate *deflate; struct deflate_chunk out; @@ -64,14 +64,12 @@ int zlib_deflate ( enum deflate_format format, struct deflate_chunk *in, /* (Re)initialise decompressor */ deflate_init ( deflate, format ); - /* (Re)initialise input chunk */ - in->offset = 0; - /* Initialise output chunk */ deflate_chunk_init ( &out, extracted->data, 0, extracted->len ); /* Decompress data */ - if ( ( rc = deflate_inflate ( deflate, in, &out ) ) != 0 ) { + if ( ( rc = deflate_inflate ( deflate, data, len, + &out ) ) != 0 ) { DBGC ( extracted, "ZLIB %p could not decompress: %s\n", extracted, strerror ( rc ) ); goto err_inflate; @@ -116,14 +114,11 @@ int zlib_deflate ( enum deflate_format format, struct deflate_chunk *in, * @ret rc Return status code */ static int zlib_extract ( struct image *image, struct image *extracted ) { - struct deflate_chunk in; int rc; - /* Initialise input chunk */ - deflate_chunk_init ( &in, image->data, 0, image->len ); - /* Decompress image */ - if ( ( rc = zlib_deflate ( DEFLATE_ZLIB, &in, extracted ) ) != 0 ) + if ( ( rc = zlib_deflate ( DEFLATE_ZLIB, image->data, image->len, + extracted ) ) != 0 ) return rc; return 0; @@ -136,17 +131,17 @@ static int zlib_extract ( struct image *image, struct image *extracted ) { * @ret rc Return status code */ static int zlib_probe ( struct image *image ) { - union zlib_magic magic; + const union zlib_magic *magic; /* Sanity check */ - if ( image->len < sizeof ( magic ) ) { + if ( image->len < sizeof ( *magic ) ) { DBGC ( image, "ZLIB %p image too short\n", image ); return -ENOEXEC; } + magic = image->data; /* Check magic header */ - copy_from_user ( &magic, image->data, 0, sizeof ( magic ) ); - if ( ! zlib_magic_is_valid ( &magic ) ) { + if ( ! zlib_magic_is_valid ( magic ) ) { DBGC ( image, "ZLIB %p invalid magic data\n", image ); return -ENOEXEC; } diff --git a/src/include/ipxe/deflate.h b/src/include/ipxe/deflate.h index b751aa9a3..67292d77e 100644 --- a/src/include/ipxe/deflate.h +++ b/src/include/ipxe/deflate.h @@ -11,7 +11,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include -#include /** Compression formats */ enum deflate_format { @@ -163,6 +162,11 @@ struct deflate { /** Format */ enum deflate_format format; + /** Current input data pointer */ + const uint8_t *in; + /** End of input data pointer */ + const uint8_t *end; + /** Accumulator */ uint32_t accumulator; /** Bit-reversed accumulator @@ -240,7 +244,7 @@ struct deflate { /** A chunk of data */ struct deflate_chunk { /** Data */ - userptr_t data; + void *data; /** Current offset */ size_t offset; /** Length of data */ @@ -256,7 +260,7 @@ struct deflate_chunk { * @v len Length */ static inline __attribute__ (( always_inline )) void -deflate_chunk_init ( struct deflate_chunk *chunk, userptr_t data, +deflate_chunk_init ( struct deflate_chunk *chunk, void *data, size_t offset, size_t len ) { chunk->data = data; @@ -277,7 +281,7 @@ static inline int deflate_finished ( struct deflate *deflate ) { extern void deflate_init ( struct deflate *deflate, enum deflate_format format ); extern int deflate_inflate ( struct deflate *deflate, - struct deflate_chunk *in, + const void *data, size_t len, struct deflate_chunk *out ); #endif /* _IPXE_DEFLATE_H */ diff --git a/src/include/ipxe/zlib.h b/src/include/ipxe/zlib.h index 29016c38e..3b0866bd1 100644 --- a/src/include/ipxe/zlib.h +++ b/src/include/ipxe/zlib.h @@ -28,15 +28,15 @@ union zlib_magic { * @v magic Magic header * @ret is_valid Magic header is valid */ -static inline int zlib_magic_is_valid ( union zlib_magic *magic ) { +static inline int zlib_magic_is_valid ( const union zlib_magic *magic ) { /* Check magic value as per RFC 6713 */ return ( ( ( magic->cmf & 0x8f ) == 0x08 ) && ( ( be16_to_cpu ( magic->check ) % 31 ) == 0 ) ); } -extern int zlib_deflate ( enum deflate_format format, struct deflate_chunk *in, - struct image *extracted ); +extern int zlib_deflate ( enum deflate_format format, const void *data, + size_t len, struct image *extracted ); extern struct image_type zlib_image_type __image_type ( PROBE_NORMAL ); diff --git a/src/tests/deflate_test.c b/src/tests/deflate_test.c index 20ff5b9a2..f7086b45d 100644 --- a/src/tests/deflate_test.c +++ b/src/tests/deflate_test.c @@ -156,19 +156,18 @@ static void deflate_okx ( struct deflate *deflate, struct deflate_test *test, struct deflate_test_fragments *frags, const char *file, unsigned int line ) { - uint8_t data[ test->expected_len ]; - struct deflate_chunk in; - struct deflate_chunk out; - size_t frag_len = -1UL; - size_t offset = 0; + uint8_t buf[ test->expected_len ]; + const void *data = test->compressed; size_t remaining = test->compressed_len; + size_t frag_len = -1UL; + struct deflate_chunk out; unsigned int i; /* Initialise decompressor */ deflate_init ( deflate, test->format ); /* Initialise output chunk */ - deflate_chunk_init ( &out, virt_to_user ( data ), 0, sizeof ( data ) ); + deflate_chunk_init ( &out, buf, 0, sizeof ( buf ) ); /* Process input (in fragments, if applicable) */ for ( i = 0 ; i < ( sizeof ( frags->len ) / @@ -179,16 +178,15 @@ static void deflate_okx ( struct deflate *deflate, frag_len = frags->len[i]; if ( frag_len > remaining ) frag_len = remaining; - deflate_chunk_init ( &in, virt_to_user ( test->compressed ), - offset, ( offset + frag_len ) ); /* Decompress this fragment */ - okx ( deflate_inflate ( deflate, &in, &out ) == 0, file, line ); - okx ( in.len == ( offset + frag_len ), file, line ); - okx ( in.offset == in.len, file, line ); + okx ( deflate_inflate ( deflate, data, frag_len, + &out ) == 0, file, line ); + okx ( deflate->in == ( data + frag_len ), file, line ); + okx ( deflate->end == ( data + frag_len ), file, line ); /* Move to next fragment */ - offset = in.offset; + data += frag_len; remaining -= frag_len; if ( ! remaining ) break; @@ -199,9 +197,13 @@ static void deflate_okx ( struct deflate *deflate, /* Check decompression has terminated as expected */ okx ( deflate_finished ( deflate ), file, line ); - okx ( offset == test->compressed_len, file, line ); + okx ( deflate->in == ( test->compressed + test->compressed_len ), + file, line ); + okx ( deflate->end == ( test->compressed + test->compressed_len ), + file, line ); okx ( out.offset == test->expected_len, file, line ); - okx ( memcmp ( data, test->expected, test->expected_len ) == 0, + okx ( out.data == buf, file, line ); + okx ( memcmp ( out.data, test->expected, test->expected_len ) == 0, file, line ); } #define deflate_ok( deflate, test, frags ) \ diff --git a/src/tests/gzip_test.c b/src/tests/gzip_test.c index 9226b4c26..6fd0ec854 100644 --- a/src/tests/gzip_test.c +++ b/src/tests/gzip_test.c @@ -33,6 +33,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #undef NDEBUG #include +#include #include #include #include @@ -114,8 +115,7 @@ static void gzip_okx ( struct gzip_test *test, const char *file, struct image *extracted; /* Construct compressed image */ - image = image_memory ( test->compressed_name, - virt_to_user ( test->compressed ), + image = image_memory ( test->compressed_name, test->compressed, test->compressed_len ); okx ( image != NULL, file, line ); okx ( image->len == test->compressed_len, file, line ); @@ -128,7 +128,7 @@ static void gzip_okx ( struct gzip_test *test, const char *file, /* Verify extracted image content */ okx ( extracted->len == test->expected_len, file, line ); - okx ( memcmp ( extracted->data, virt_to_user ( test->expected ), + okx ( memcmp ( extracted->data, test->expected, test->expected_len ) == 0, file, line ); /* Verify extracted image name */ diff --git a/src/tests/zlib_test.c b/src/tests/zlib_test.c index 2efdcbad8..807c5e429 100644 --- a/src/tests/zlib_test.c +++ b/src/tests/zlib_test.c @@ -89,8 +89,7 @@ static void zlib_okx ( struct zlib_test *test, const char *file, struct image *extracted; /* Construct compressed image */ - image = image_memory ( test->compressed_name, - virt_to_user ( test->compressed ), + image = image_memory ( test->compressed_name, test->compressed, test->compressed_len ); okx ( image != NULL, file, line ); okx ( image->len == test->compressed_len, file, line ); @@ -103,7 +102,7 @@ static void zlib_okx ( struct zlib_test *test, const char *file, /* Verify extracted image content */ okx ( extracted->len == test->expected_len, file, line ); - okx ( memcmp ( extracted->data, virt_to_user ( test->expected ), + okx ( memcmp ( extracted->data, test->expected, test->expected_len ) == 0, file, line ); /* Verify extracted image name */