mirror of https://github.com/madler/zlib
Port Fix InflateBack corner case
This handles the case where a zlib user could rely on InflateBack
API to decompress content.
The NEON optimization assumes that it can perform wide stores, sometimes
overwriting data on the output pointer (but never overflowing the buffer
end as it has enough room for the write).
For infback there is no such guarantees (i.e. no extra wiggle room),
which can result in illegal operations. This patch fixes the potential
issue by falling back to the non-optimized code for such cases.
Also it adds some comments about the entry assumptions in inflate and
writes out a defined value at the write buffer to identify where
the real data has ended (helpful while debugging).
For reference, please see:
0bb1104079
Change-Id: Iffbda9eb5e08a661aa15c6e3d1c59b678cc23b2c
This commit is contained in:
parent
390b2713be
commit
267e6f2017
|
@ -139,9 +139,8 @@ if(CMAKE_COMPILER_IS_GNUCC)
|
|||
|
||||
if(ARM_NEON)
|
||||
list(REMOVE_ITEM ZLIB_SRCS inflate.c)
|
||||
list(REMOVE_ITEM ZLIB_SRCS inffast.c)
|
||||
set(ZLIB_ARM_NEON_HDRS contrib/arm/chunkcopy.h)
|
||||
set(ZLIB_ARM_NEON contrib/arm/inflate.c contrib/arm/inffast.c)
|
||||
set(ZLIB_ARM_NEON_HDRS contrib/arm/chunkcopy.h contrib/arm/inffast_chunk.h)
|
||||
set(ZLIB_ARM_NEON contrib/arm/inflate.c contrib/arm/inffast_chunk.c)
|
||||
add_definitions(-DARM_NEON)
|
||||
set(COMPILER ${CMAKE_C_COMPILER})
|
||||
# NEON is mandatory in ARMv8.
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
#include "zutil.h"
|
||||
#include "inftrees.h"
|
||||
#include "inflate.h"
|
||||
#include "inffast.h"
|
||||
#include "chunkcopy.h"
|
||||
#include "contrib/arm/inffast_chunk.h"
|
||||
#include "contrib/arm/chunkcopy.h"
|
||||
|
||||
#ifdef ASMINF
|
||||
# pragma message("Assembler code may have bugs -- use at your own risk")
|
||||
|
@ -28,6 +28,10 @@
|
|||
strm->avail_out >= 258
|
||||
start >= strm->avail_out
|
||||
state->bits < 8
|
||||
strm->next_out[0..strm->avail_out] does not overlap with
|
||||
strm->next_in[0..strm->avail_in]
|
||||
strm->state->window is allocated with an additional
|
||||
CHUNKCOPY_CHUNK_SIZE-1 bytes of padding beyond strm->state->wsize
|
||||
|
||||
On return, state->mode is one of:
|
||||
|
||||
|
@ -48,7 +52,7 @@
|
|||
requires strm->avail_out >= 258 for each loop to avoid checking for
|
||||
output space.
|
||||
*/
|
||||
void ZLIB_INTERNAL inflate_fast(strm, start)
|
||||
void ZLIB_INTERNAL inflate_fast_chunk(strm, start)
|
||||
z_streamp strm;
|
||||
unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||
{
|
|
@ -0,0 +1,12 @@
|
|||
/* inffast.h -- header to use inffast.c
|
||||
* Copyright (C) 1995-2003, 2010 Mark Adler
|
||||
* Copyright (C) 2017 ARM, Inc.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It is
|
||||
part of the implementation of the compression library and is
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
void ZLIB_INTERNAL inflate_fast_chunk OF((z_streamp strm, unsigned start));
|
|
@ -83,7 +83,7 @@
|
|||
#include "zutil.h"
|
||||
#include "inftrees.h"
|
||||
#include "inflate.h"
|
||||
#include "inffast.h"
|
||||
#include "contrib/arm/inffast_chunk.h"
|
||||
#include "contrib/arm/chunkcopy.h"
|
||||
|
||||
#ifdef MAKEFIXED
|
||||
|
@ -1056,7 +1056,7 @@ int flush;
|
|||
case LEN:
|
||||
if (have >= 6 && left >= 258) {
|
||||
RESTORE();
|
||||
inflate_fast(strm, out);
|
||||
inflate_fast_chunk(strm, out);
|
||||
LOAD();
|
||||
if (state->mode == TYPE)
|
||||
state->back = -1;
|
||||
|
@ -1262,6 +1262,16 @@ int flush;
|
|||
Note: a memory error from inflate() is non-recoverable.
|
||||
*/
|
||||
inf_leave:
|
||||
/* We write a defined value in the unused space to help mark
|
||||
* where the stream has ended. We don't use zeros as that can
|
||||
* mislead clients relying on undefined behavior (i.e. assuming
|
||||
* that the data is over when the buffer has a zero/null value).
|
||||
*/
|
||||
if (left >= CHUNKCOPY_CHUNK_SIZE)
|
||||
memset(put, 0x55, CHUNKCOPY_CHUNK_SIZE);
|
||||
else
|
||||
memset(put, 0x55, left);
|
||||
|
||||
RESTORE();
|
||||
if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
|
||||
(state->mode < CHECK || flush != Z_FINISH)))
|
||||
|
|
Loading…
Reference in New Issue