* commit '8dda0956b6565a958989af44e885b94dc9bfc9bd': StreamingZipInflater: fix mmap'd end of read
This commit is contained in:
@@ -23,6 +23,23 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TEMP_FAILURE_RETRY is defined by some, but not all, versions of
|
||||||
|
* <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's
|
||||||
|
* not already defined, then define it here.
|
||||||
|
*/
|
||||||
|
#ifndef TEMP_FAILURE_RETRY
|
||||||
|
/* Used to retry syscalls that can return EINTR. */
|
||||||
|
#define TEMP_FAILURE_RETRY(exp) ({ \
|
||||||
|
typeof (exp) _rc; \
|
||||||
|
do { \
|
||||||
|
_rc = (exp); \
|
||||||
|
} while (_rc == -1 && errno == EINTR); \
|
||||||
|
_rc; })
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline size_t min_of(size_t a, size_t b) { return (a < b) ? a : b; }
|
static inline size_t min_of(size_t a, size_t b) { return (a < b) ? a : b; }
|
||||||
|
|
||||||
@@ -135,7 +152,7 @@ ssize_t StreamingZipInflater::read(void* outBuf, size_t count) {
|
|||||||
// if we don't have any data to decode, read some in. If we're working
|
// if we don't have any data to decode, read some in. If we're working
|
||||||
// from mmapped data this won't happen, because the clipping to total size
|
// from mmapped data this won't happen, because the clipping to total size
|
||||||
// will prevent reading off the end of the mapped input chunk.
|
// will prevent reading off the end of the mapped input chunk.
|
||||||
if (mInflateState.avail_in == 0) {
|
if ((mInflateState.avail_in == 0) && (mDataMap == NULL)) {
|
||||||
int err = readNextChunk();
|
int err = readNextChunk();
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
ALOGE("Unable to access asset data: %d", err);
|
ALOGE("Unable to access asset data: %d", err);
|
||||||
@@ -191,11 +208,10 @@ int StreamingZipInflater::readNextChunk() {
|
|||||||
if (mInNextChunkOffset < mInTotalSize) {
|
if (mInNextChunkOffset < mInTotalSize) {
|
||||||
size_t toRead = min_of(mInBufSize, mInTotalSize - mInNextChunkOffset);
|
size_t toRead = min_of(mInBufSize, mInTotalSize - mInNextChunkOffset);
|
||||||
if (toRead > 0) {
|
if (toRead > 0) {
|
||||||
ssize_t didRead = ::read(mFd, mInBuf, toRead);
|
ssize_t didRead = TEMP_FAILURE_RETRY(::read(mFd, mInBuf, toRead));
|
||||||
//ALOGV("Reading input chunk, size %08x didread %08x", toRead, didRead);
|
//ALOGV("Reading input chunk, size %08x didread %08x", toRead, didRead);
|
||||||
if (didRead < 0) {
|
if (didRead < 0) {
|
||||||
// TODO: error
|
ALOGE("Error reading asset data: %s", strerror(errno));
|
||||||
ALOGE("Error reading asset data");
|
|
||||||
return didRead;
|
return didRead;
|
||||||
} else {
|
} else {
|
||||||
mInNextChunkOffset += didRead;
|
mInNextChunkOffset += didRead;
|
||||||
|
|||||||
Reference in New Issue
Block a user