mirror of
https://github.com/ipxe/ipxe
synced 2025-12-18 18:40:24 +03:00
[png] Remove userptr_t from PNG image parsing
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
175
src/image/png.c
175
src/image/png.c
@@ -197,12 +197,12 @@ static size_t png_scanline_len ( struct png_context *png,
|
|||||||
*/
|
*/
|
||||||
static int png_image_header ( struct image *image, struct png_context *png,
|
static int png_image_header ( struct image *image, struct png_context *png,
|
||||||
size_t len ) {
|
size_t len ) {
|
||||||
struct png_image_header ihdr;
|
const struct png_image_header *ihdr;
|
||||||
struct png_interlace interlace;
|
struct png_interlace interlace;
|
||||||
unsigned int pass;
|
unsigned int pass;
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
if ( len != sizeof ( ihdr ) ) {
|
if ( len != sizeof ( *ihdr ) ) {
|
||||||
DBGC ( image, "PNG %s invalid IHDR length %zd\n",
|
DBGC ( image, "PNG %s invalid IHDR length %zd\n",
|
||||||
image->name, len );
|
image->name, len );
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -213,32 +213,32 @@ static int png_image_header ( struct image *image, struct png_context *png,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Extract image header */
|
/* Extract image header */
|
||||||
copy_from_user ( &ihdr, image->data, png->offset, len );
|
ihdr = ( image->data + png->offset );
|
||||||
DBGC ( image, "PNG %s %dx%d depth %d type %d compression %d filter %d "
|
DBGC ( image, "PNG %s %dx%d depth %d type %d compression %d filter %d "
|
||||||
"interlace %d\n", image->name, ntohl ( ihdr.width ),
|
"interlace %d\n", image->name, ntohl ( ihdr->width ),
|
||||||
ntohl ( ihdr.height ), ihdr.depth, ihdr.colour_type,
|
ntohl ( ihdr->height ), ihdr->depth, ihdr->colour_type,
|
||||||
ihdr.compression, ihdr.filter, ihdr.interlace );
|
ihdr->compression, ihdr->filter, ihdr->interlace );
|
||||||
|
|
||||||
/* Sanity checks */
|
/* Sanity checks */
|
||||||
if ( ihdr.compression >= PNG_COMPRESSION_UNKNOWN ) {
|
if ( ihdr->compression >= PNG_COMPRESSION_UNKNOWN ) {
|
||||||
DBGC ( image, "PNG %s unknown compression method %d\n",
|
DBGC ( image, "PNG %s unknown compression method %d\n",
|
||||||
image->name, ihdr.compression );
|
image->name, ihdr->compression );
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
if ( ihdr.filter >= PNG_FILTER_UNKNOWN ) {
|
if ( ihdr->filter >= PNG_FILTER_UNKNOWN ) {
|
||||||
DBGC ( image, "PNG %s unknown filter method %d\n",
|
DBGC ( image, "PNG %s unknown filter method %d\n",
|
||||||
image->name, ihdr.filter );
|
image->name, ihdr->filter );
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
if ( ihdr.interlace >= PNG_INTERLACE_UNKNOWN ) {
|
if ( ihdr->interlace >= PNG_INTERLACE_UNKNOWN ) {
|
||||||
DBGC ( image, "PNG %s unknown interlace method %d\n",
|
DBGC ( image, "PNG %s unknown interlace method %d\n",
|
||||||
image->name, ihdr.interlace );
|
image->name, ihdr->interlace );
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate pixel buffer */
|
/* Allocate pixel buffer */
|
||||||
png->pixbuf = alloc_pixbuf ( ntohl ( ihdr.width ),
|
png->pixbuf = alloc_pixbuf ( ntohl ( ihdr->width ),
|
||||||
ntohl ( ihdr.height ) );
|
ntohl ( ihdr->height ) );
|
||||||
if ( ! png->pixbuf ) {
|
if ( ! png->pixbuf ) {
|
||||||
DBGC ( image, "PNG %s could not allocate pixel buffer\n",
|
DBGC ( image, "PNG %s could not allocate pixel buffer\n",
|
||||||
image->name );
|
image->name );
|
||||||
@@ -246,7 +246,7 @@ static int png_image_header ( struct image *image, struct png_context *png,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Extract bit depth */
|
/* Extract bit depth */
|
||||||
png->depth = ihdr.depth;
|
png->depth = ihdr->depth;
|
||||||
if ( ( png->depth == 0 ) ||
|
if ( ( png->depth == 0 ) ||
|
||||||
( ( png->depth & ( png->depth - 1 ) ) != 0 ) ) {
|
( ( png->depth & ( png->depth - 1 ) ) != 0 ) ) {
|
||||||
DBGC ( image, "PNG %s invalid depth %d\n",
|
DBGC ( image, "PNG %s invalid depth %d\n",
|
||||||
@@ -255,17 +255,17 @@ static int png_image_header ( struct image *image, struct png_context *png,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate number of channels */
|
/* Calculate number of channels */
|
||||||
png->colour_type = ihdr.colour_type;
|
png->colour_type = ihdr->colour_type;
|
||||||
png->channels = 1;
|
png->channels = 1;
|
||||||
if ( ! ( ihdr.colour_type & PNG_COLOUR_TYPE_PALETTE ) ) {
|
if ( ! ( ihdr->colour_type & PNG_COLOUR_TYPE_PALETTE ) ) {
|
||||||
if ( ihdr.colour_type & PNG_COLOUR_TYPE_RGB )
|
if ( ihdr->colour_type & PNG_COLOUR_TYPE_RGB )
|
||||||
png->channels += 2;
|
png->channels += 2;
|
||||||
if ( ihdr.colour_type & PNG_COLOUR_TYPE_ALPHA )
|
if ( ihdr->colour_type & PNG_COLOUR_TYPE_ALPHA )
|
||||||
png->channels += 1;
|
png->channels += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate number of interlace passes */
|
/* Calculate number of interlace passes */
|
||||||
png->passes = png_interlace_passes[ihdr.interlace];
|
png->passes = png_interlace_passes[ihdr->interlace];
|
||||||
|
|
||||||
/* Calculate length of raw data buffer */
|
/* Calculate length of raw data buffer */
|
||||||
for ( pass = 0 ; pass < png->passes ; pass++ ) {
|
for ( pass = 0 ; pass < png->passes ; pass++ ) {
|
||||||
@@ -297,30 +297,28 @@ static int png_image_header ( struct image *image, struct png_context *png,
|
|||||||
*/
|
*/
|
||||||
static int png_palette ( struct image *image, struct png_context *png,
|
static int png_palette ( struct image *image, struct png_context *png,
|
||||||
size_t len ) {
|
size_t len ) {
|
||||||
size_t offset = png->offset;
|
const struct png_palette_entry *palette;
|
||||||
struct png_palette_entry palette;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
/* Populate palette */
|
/* Populate palette */
|
||||||
|
palette = ( image->data + png->offset );
|
||||||
for ( i = 0 ; i < ( sizeof ( png->palette ) /
|
for ( i = 0 ; i < ( sizeof ( png->palette ) /
|
||||||
sizeof ( png->palette[0] ) ) ; i++ ) {
|
sizeof ( png->palette[0] ) ) ; i++ ) {
|
||||||
|
|
||||||
/* Stop when we run out of palette data */
|
/* Stop when we run out of palette data */
|
||||||
if ( len < sizeof ( palette ) )
|
if ( len < sizeof ( *palette ) )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Extract palette entry */
|
/* Extract palette entry */
|
||||||
copy_from_user ( &palette, image->data, offset,
|
png->palette[i] = ( ( palette->red << 16 ) |
|
||||||
sizeof ( palette ) );
|
( palette->green << 8 ) |
|
||||||
png->palette[i] = ( ( palette.red << 16 ) |
|
( palette->blue << 0 ) );
|
||||||
( palette.green << 8 ) |
|
|
||||||
( palette.blue << 0 ) );
|
|
||||||
DBGC2 ( image, "PNG %s palette entry %d is %#06x\n",
|
DBGC2 ( image, "PNG %s palette entry %d is %#06x\n",
|
||||||
image->name, i, png->palette[i] );
|
image->name, i, png->palette[i] );
|
||||||
|
|
||||||
/* Move to next entry */
|
/* Move to next entry */
|
||||||
offset += sizeof ( palette );
|
palette++;
|
||||||
len -= sizeof ( palette );
|
len -= sizeof ( *palette );
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -503,17 +501,16 @@ static struct png_filter png_filters[] = {
|
|||||||
*/
|
*/
|
||||||
static int png_unfilter_pass ( struct image *image, struct png_context *png,
|
static int png_unfilter_pass ( struct image *image, struct png_context *png,
|
||||||
struct png_interlace *interlace ) {
|
struct png_interlace *interlace ) {
|
||||||
size_t offset = png->raw.offset;
|
|
||||||
size_t pixel_len = png_pixel_len ( png );
|
size_t pixel_len = png_pixel_len ( png );
|
||||||
size_t scanline_len = png_scanline_len ( png, interlace );
|
size_t scanline_len = png_scanline_len ( png, interlace );
|
||||||
|
uint8_t *data = ( png->raw.data + png->raw.offset );
|
||||||
struct png_filter *filter;
|
struct png_filter *filter;
|
||||||
unsigned int scanline;
|
unsigned int scanline;
|
||||||
unsigned int byte;
|
unsigned int byte;
|
||||||
uint8_t filter_type;
|
unsigned int filter_type;
|
||||||
uint8_t left;
|
unsigned int left;
|
||||||
uint8_t above;
|
unsigned int above;
|
||||||
uint8_t above_left;
|
unsigned int above_left;
|
||||||
uint8_t current;
|
|
||||||
|
|
||||||
/* On the first scanline of a pass, above bytes are assumed to
|
/* On the first scanline of a pass, above bytes are assumed to
|
||||||
* be zero.
|
* be zero.
|
||||||
@@ -524,8 +521,7 @@ static int png_unfilter_pass ( struct image *image, struct png_context *png,
|
|||||||
for ( scanline = 0 ; scanline < interlace->height ; scanline++ ) {
|
for ( scanline = 0 ; scanline < interlace->height ; scanline++ ) {
|
||||||
|
|
||||||
/* Extract filter byte and determine filter type */
|
/* Extract filter byte and determine filter type */
|
||||||
copy_from_user ( &filter_type, png->raw.data, offset++,
|
filter_type = *(data++);
|
||||||
sizeof ( filter_type ) );
|
|
||||||
if ( filter_type >= ( sizeof ( png_filters ) /
|
if ( filter_type >= ( sizeof ( png_filters ) /
|
||||||
sizeof ( png_filters[0] ) ) ) {
|
sizeof ( png_filters[0] ) ) ) {
|
||||||
DBGC ( image, "PNG %s unknown filter type %d\n",
|
DBGC ( image, "PNG %s unknown filter type %d\n",
|
||||||
@@ -547,35 +543,24 @@ static int png_unfilter_pass ( struct image *image, struct png_context *png,
|
|||||||
for ( byte = 0 ; byte < ( scanline_len - 1 ) ; byte++ ) {
|
for ( byte = 0 ; byte < ( scanline_len - 1 ) ; byte++ ) {
|
||||||
|
|
||||||
/* Extract predictor bytes, if applicable */
|
/* Extract predictor bytes, if applicable */
|
||||||
if ( byte >= pixel_len ) {
|
if ( byte >= pixel_len )
|
||||||
copy_from_user ( &left, png->raw.data,
|
left = *( data - pixel_len );
|
||||||
( offset - pixel_len ),
|
if ( scanline > 0 )
|
||||||
sizeof ( left ) );
|
above = *( data - scanline_len );
|
||||||
}
|
|
||||||
if ( scanline > 0 ) {
|
|
||||||
copy_from_user ( &above, png->raw.data,
|
|
||||||
( offset - scanline_len ),
|
|
||||||
sizeof ( above ) );
|
|
||||||
}
|
|
||||||
if ( ( scanline > 0 ) && ( byte >= pixel_len ) ) {
|
if ( ( scanline > 0 ) && ( byte >= pixel_len ) ) {
|
||||||
copy_from_user ( &above_left, png->raw.data,
|
above_left = *( data - scanline_len -
|
||||||
( offset - scanline_len -
|
pixel_len );
|
||||||
pixel_len ),
|
|
||||||
sizeof ( above_left ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unfilter current byte */
|
/* Unfilter current byte */
|
||||||
copy_from_user ( ¤t, png->raw.data,
|
*data = filter->unfilter ( *data, left, above,
|
||||||
offset, sizeof ( current ) );
|
|
||||||
current = filter->unfilter ( current, left, above,
|
|
||||||
above_left );
|
above_left );
|
||||||
copy_to_user ( png->raw.data, offset++,
|
data++;
|
||||||
¤t, sizeof ( current ) );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update offset */
|
/* Update offset */
|
||||||
png->raw.offset = offset;
|
png->raw.offset = ( ( ( void * ) data ) - png->raw.data );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -650,16 +635,16 @@ static inline unsigned int png_pixel ( unsigned int raw, unsigned int alpha,
|
|||||||
static void png_pixels_pass ( struct image *image,
|
static void png_pixels_pass ( struct image *image,
|
||||||
struct png_context *png,
|
struct png_context *png,
|
||||||
struct png_interlace *interlace ) {
|
struct png_interlace *interlace ) {
|
||||||
size_t raw_offset = png->raw.offset;
|
|
||||||
uint8_t channel[png->channels];
|
uint8_t channel[png->channels];
|
||||||
int is_indexed = ( png->colour_type & PNG_COLOUR_TYPE_PALETTE );
|
int is_indexed = ( png->colour_type & PNG_COLOUR_TYPE_PALETTE );
|
||||||
int is_rgb = ( png->colour_type & PNG_COLOUR_TYPE_RGB );
|
int is_rgb = ( png->colour_type & PNG_COLOUR_TYPE_RGB );
|
||||||
int has_alpha = ( png->colour_type & PNG_COLOUR_TYPE_ALPHA );
|
int has_alpha = ( png->colour_type & PNG_COLOUR_TYPE_ALPHA );
|
||||||
size_t pixbuf_y_offset;
|
const uint8_t *data = ( png->raw.data + png->raw.offset );
|
||||||
size_t pixbuf_offset;
|
size_t data_stride;
|
||||||
size_t pixbuf_x_stride;
|
unsigned int pixbuf_y_index;
|
||||||
size_t pixbuf_y_stride;
|
unsigned int pixbuf_index;
|
||||||
size_t raw_stride;
|
unsigned int pixbuf_x_stride;
|
||||||
|
unsigned int pixbuf_y_stride;
|
||||||
unsigned int y;
|
unsigned int y;
|
||||||
unsigned int x;
|
unsigned int x;
|
||||||
unsigned int c;
|
unsigned int c;
|
||||||
@@ -676,17 +661,16 @@ static void png_pixels_pass ( struct image *image,
|
|||||||
* as a bit depth of 8 with a stride of more than one.
|
* as a bit depth of 8 with a stride of more than one.
|
||||||
*/
|
*/
|
||||||
depth = png->depth;
|
depth = png->depth;
|
||||||
raw_stride = ( ( depth + 7 ) / 8 );
|
data_stride = ( ( depth + 7 ) / 8 );
|
||||||
if ( depth > 8 )
|
if ( depth > 8 )
|
||||||
depth = 8;
|
depth = 8;
|
||||||
max = ( ( 1 << depth ) - 1 );
|
max = ( ( 1 << depth ) - 1 );
|
||||||
|
|
||||||
/* Calculate pixel buffer offset and strides */
|
/* Calculate pixel buffer offset and strides */
|
||||||
pixbuf_y_offset = ( ( ( interlace->y_indent * png->pixbuf->width ) +
|
pixbuf_y_index = ( ( ( interlace->y_indent * png->pixbuf->width ) +
|
||||||
interlace->x_indent ) * sizeof ( pixel ) );
|
interlace->x_indent ) );
|
||||||
pixbuf_x_stride = ( interlace->x_stride * sizeof ( pixel ) );
|
pixbuf_x_stride = interlace->x_stride;
|
||||||
pixbuf_y_stride = ( interlace->y_stride * png->pixbuf->width *
|
pixbuf_y_stride = ( interlace->y_stride * png->pixbuf->width );
|
||||||
sizeof ( pixel ) );
|
|
||||||
DBGC2 ( image, "PNG %s pass %d %dx%d at (%d,%d) stride (%d,%d)\n",
|
DBGC2 ( image, "PNG %s pass %d %dx%d at (%d,%d) stride (%d,%d)\n",
|
||||||
image->name, interlace->pass, interlace->width,
|
image->name, interlace->pass, interlace->width,
|
||||||
interlace->height, interlace->x_indent, interlace->y_indent,
|
interlace->height, interlace->x_indent, interlace->y_indent,
|
||||||
@@ -696,11 +680,11 @@ static void png_pixels_pass ( struct image *image,
|
|||||||
for ( y = 0 ; y < interlace->height ; y++ ) {
|
for ( y = 0 ; y < interlace->height ; y++ ) {
|
||||||
|
|
||||||
/* Skip filter byte */
|
/* Skip filter byte */
|
||||||
raw_offset++;
|
data++;
|
||||||
|
|
||||||
/* Iterate over each pixel in turn */
|
/* Iterate over each pixel in turn */
|
||||||
bits = depth;
|
bits = depth;
|
||||||
pixbuf_offset = pixbuf_y_offset;
|
pixbuf_index = pixbuf_y_index;
|
||||||
for ( x = 0 ; x < interlace->width ; x++ ) {
|
for ( x = 0 ; x < interlace->width ; x++ ) {
|
||||||
|
|
||||||
/* Extract sample value */
|
/* Extract sample value */
|
||||||
@@ -710,11 +694,8 @@ static void png_pixels_pass ( struct image *image,
|
|||||||
current <<= depth;
|
current <<= depth;
|
||||||
bits -= depth;
|
bits -= depth;
|
||||||
if ( ! bits ) {
|
if ( ! bits ) {
|
||||||
copy_from_user ( ¤t,
|
current = *data;
|
||||||
png->raw.data,
|
data += data_stride;
|
||||||
raw_offset,
|
|
||||||
sizeof ( current ) );
|
|
||||||
raw_offset += raw_stride;
|
|
||||||
bits = 8;
|
bits = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -745,17 +726,16 @@ static void png_pixels_pass ( struct image *image,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Store pixel */
|
/* Store pixel */
|
||||||
copy_to_user ( png->pixbuf->data, pixbuf_offset,
|
png->pixbuf->data[pixbuf_index] = pixel;
|
||||||
&pixel, sizeof ( pixel ) );
|
pixbuf_index += pixbuf_x_stride;
|
||||||
pixbuf_offset += pixbuf_x_stride;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move to next output row */
|
/* Move to next output row */
|
||||||
pixbuf_y_offset += pixbuf_y_stride;
|
pixbuf_y_index += pixbuf_y_stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update offset */
|
/* Update offset */
|
||||||
png->raw.offset = raw_offset;
|
png->raw.offset = ( ( ( const void * ) data ) - png->raw.data );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -903,8 +883,8 @@ static int png_chunk ( struct image *image, struct png_context *png,
|
|||||||
*/
|
*/
|
||||||
static int png_pixbuf ( struct image *image, struct pixel_buffer **pixbuf ) {
|
static int png_pixbuf ( struct image *image, struct pixel_buffer **pixbuf ) {
|
||||||
struct png_context *png;
|
struct png_context *png;
|
||||||
struct png_chunk_header header;
|
const struct png_chunk_header *header;
|
||||||
struct png_chunk_footer footer;
|
const struct png_chunk_footer *footer;
|
||||||
size_t remaining;
|
size_t remaining;
|
||||||
size_t chunk_len;
|
size_t chunk_len;
|
||||||
int rc;
|
int rc;
|
||||||
@@ -923,20 +903,19 @@ static int png_pixbuf ( struct image *image, struct pixel_buffer **pixbuf ) {
|
|||||||
|
|
||||||
/* Extract chunk header */
|
/* Extract chunk header */
|
||||||
remaining = ( image->len - png->offset );
|
remaining = ( image->len - png->offset );
|
||||||
if ( remaining < ( sizeof ( header ) + sizeof ( footer ) ) ) {
|
if ( remaining < ( sizeof ( *header ) + sizeof ( *footer ) ) ){
|
||||||
DBGC ( image, "PNG %s truncated chunk header/footer "
|
DBGC ( image, "PNG %s truncated chunk header/footer "
|
||||||
"at offset %zd\n", image->name, png->offset );
|
"at offset %zd\n", image->name, png->offset );
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
goto err_truncated;
|
goto err_truncated;
|
||||||
}
|
}
|
||||||
copy_from_user ( &header, image->data, png->offset,
|
header = ( image->data + png->offset );
|
||||||
sizeof ( header ) );
|
png->offset += sizeof ( *header );
|
||||||
png->offset += sizeof ( header );
|
|
||||||
|
|
||||||
/* Validate chunk length */
|
/* Validate chunk length */
|
||||||
chunk_len = ntohl ( header.len );
|
chunk_len = ntohl ( header->len );
|
||||||
if ( chunk_len > ( remaining - sizeof ( header ) -
|
if ( chunk_len > ( remaining - sizeof ( *header ) -
|
||||||
sizeof ( footer ) ) ) {
|
sizeof ( *footer ) ) ) {
|
||||||
DBGC ( image, "PNG %s truncated chunk data at offset "
|
DBGC ( image, "PNG %s truncated chunk data at offset "
|
||||||
"%zd\n", image->name, png->offset );
|
"%zd\n", image->name, png->offset );
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
@@ -944,17 +923,17 @@ static int png_pixbuf ( struct image *image, struct pixel_buffer **pixbuf ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Handle chunk */
|
/* Handle chunk */
|
||||||
if ( ( rc = png_chunk ( image, png, header.type,
|
if ( ( rc = png_chunk ( image, png, header->type,
|
||||||
chunk_len ) ) != 0 )
|
chunk_len ) ) != 0 )
|
||||||
goto err_chunk;
|
goto err_chunk;
|
||||||
|
|
||||||
/* Move to next chunk */
|
/* Move to next chunk */
|
||||||
png->offset += ( chunk_len + sizeof ( footer ) );
|
png->offset += ( chunk_len + sizeof ( *footer ) );
|
||||||
|
|
||||||
} while ( png->offset < image->len );
|
} while ( png->offset < image->len );
|
||||||
|
|
||||||
/* Check that we finished with an IEND chunk */
|
/* Check that we finished with an IEND chunk */
|
||||||
if ( header.type != htonl ( PNG_TYPE_IEND ) ) {
|
if ( header->type != htonl ( PNG_TYPE_IEND ) ) {
|
||||||
DBGC ( image, "PNG %s did not finish with IEND\n",
|
DBGC ( image, "PNG %s did not finish with IEND\n",
|
||||||
image->name );
|
image->name );
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
@@ -984,17 +963,17 @@ static int png_pixbuf ( struct image *image, struct pixel_buffer **pixbuf ) {
|
|||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int png_probe ( struct image *image ) {
|
static int png_probe ( struct image *image ) {
|
||||||
struct png_signature signature;
|
const struct png_signature *signature;
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
if ( image->len < sizeof ( signature ) ) {
|
if ( image->len < sizeof ( *signature ) ) {
|
||||||
DBGC ( image, "PNG %s is too short\n", image->name );
|
DBGC ( image, "PNG %s is too short\n", image->name );
|
||||||
return -ENOEXEC;
|
return -ENOEXEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check signature */
|
/* Check signature */
|
||||||
copy_from_user ( &signature, image->data, 0, sizeof ( signature ) );
|
signature = image->data;
|
||||||
if ( memcmp ( &signature, &png_signature, sizeof ( signature ) ) != 0 ){
|
if ( memcmp ( signature, &png_signature, sizeof ( *signature ) ) != 0 ){
|
||||||
DBGC ( image, "PNG %s has invalid signature\n", image->name );
|
DBGC ( image, "PNG %s has invalid signature\n", image->name );
|
||||||
return -ENOEXEC;
|
return -ENOEXEC;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user