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