From a7eeb22efb88d8b8073d71138bcb31cb3f2c4f4d Mon Sep 17 00:00:00 2001 From: Chris Fries Date: Mon, 17 Apr 2017 21:53:16 -0500 Subject: [PATCH] libsparse: Fix verbose_error string usage Switch vnsprintf to StringPrintf to avoid off-by-one, and switch sparse_read.c to cpp. Test: fastboot flash normal image with smaller sparse limit Change-Id: Ia399b167625deb271bfd0ee3273071306d71c4d4 --- libsparse/Android.bp | 15 +++- libsparse/output_file.h | 8 +++ libsparse/sparse_file.h | 7 ++ libsparse/sparse_format.h | 8 +++ libsparse/{sparse_read.c => sparse_read.cpp} | 75 +++++++------------- 5 files changed, 60 insertions(+), 53 deletions(-) rename libsparse/{sparse_read.c => sparse_read.cpp} (89%) diff --git a/libsparse/Android.bp b/libsparse/Android.bp index dd8b5fd1d..6ec0991c7 100644 --- a/libsparse/Android.bp +++ b/libsparse/Android.bp @@ -10,17 +10,23 @@ cc_library { "sparse.c", "sparse_crc32.c", "sparse_err.c", - "sparse_read.c", + "sparse_read.cpp", ], cflags: ["-Werror"], local_include_dirs: ["include"], export_include_dirs: ["include"], target: { host: { - shared_libs: ["libz-host"], + shared_libs: [ + "libz-host", + "libbase", + ], }, android: { - shared_libs: ["libz"], + shared_libs: [ + "libz", + "libbase", + ], }, windows: { enabled: true, @@ -38,6 +44,7 @@ cc_binary { static_libs: [ "libsparse", "libz", + "libbase", ], cflags: ["-Werror"], @@ -50,6 +57,7 @@ cc_binary { static_libs: [ "libsparse", "libz", + "libbase", ], cflags: ["-Werror"], @@ -61,6 +69,7 @@ cc_binary_host { static_libs: [ "libsparse", "libz", + "libbase", ], cflags: ["-Werror"], diff --git a/libsparse/output_file.h b/libsparse/output_file.h index 474c1fc21..b67e94ecb 100644 --- a/libsparse/output_file.h +++ b/libsparse/output_file.h @@ -17,6 +17,10 @@ #ifndef _OUTPUT_FILE_H_ #define _OUTPUT_FILE_H_ +#ifdef __cplusplus +extern "C" { +#endif + #include struct output_file; @@ -38,4 +42,8 @@ void output_file_close(struct output_file *out); int read_all(int fd, void *buf, size_t len); +#ifdef __cplusplus +} +#endif + #endif diff --git a/libsparse/sparse_file.h b/libsparse/sparse_file.h index 91a12e678..763f43f67 100644 --- a/libsparse/sparse_file.h +++ b/libsparse/sparse_file.h @@ -17,6 +17,10 @@ #ifndef _LIBSPARSE_SPARSE_FILE_H_ #define _LIBSPARSE_SPARSE_FILE_H_ +#ifdef __cplusplus +extern "C" { +#endif + #include struct sparse_file { @@ -28,5 +32,8 @@ struct sparse_file { struct output_file *out; }; +#ifdef __cplusplus +} +#endif #endif /* _LIBSPARSE_SPARSE_FILE_H_ */ diff --git a/libsparse/sparse_format.h b/libsparse/sparse_format.h index c41f12a54..779e0385d 100644 --- a/libsparse/sparse_format.h +++ b/libsparse/sparse_format.h @@ -18,6 +18,10 @@ #define _LIBSPARSE_SPARSE_FORMAT_H_ #include "sparse_defs.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef struct sparse_header { __le32 magic; /* 0xed26ff3a */ __le16 major_version; /* (0x1) - reject images with higher major versions */ @@ -52,4 +56,8 @@ typedef struct chunk_header { * For a CRC32 chunk, it's 4 bytes of CRC32 */ +#ifdef __cplusplus +} +#endif + #endif diff --git a/libsparse/sparse_read.c b/libsparse/sparse_read.cpp similarity index 89% rename from libsparse/sparse_read.c rename to libsparse/sparse_read.cpp index a18820277..bd668735a 100644 --- a/libsparse/sparse_read.c +++ b/libsparse/sparse_read.cpp @@ -14,10 +14,10 @@ * limitations under the License. */ -#define _GNU_SOURCE #define _FILE_OFFSET_BITS 64 #define _LARGEFILE64_SOURCE 1 +#include #include #include #include @@ -25,17 +25,19 @@ #include #include #include -#include +#include #include #include +#include "android-base/stringprintf.h" #include "defs.h" #include "output_file.h" #include "sparse_crc32.h" #include "sparse_file.h" #include "sparse_format.h" + #if defined(__APPLE__) && defined(__MACH__) #define lseek64 lseek #define off64_t off_t @@ -45,57 +47,30 @@ #define SPARSE_HEADER_LEN (sizeof(sparse_header_t)) #define CHUNK_HEADER_LEN (sizeof(chunk_header_t)) -#define COPY_BUF_SIZE (1024U*1024U) +static constexpr int64_t COPY_BUF_SIZE = 1024 * 1024; static char *copybuf; -#define min(a, b) \ - ({ typeof(a) _a = (a); typeof(b) _b = (b); (_a < _b) ? _a : _b; }) +static std::string ErrorString(int err) +{ + if (err == -EOVERFLOW) return "EOF while reading file"; + if (err == -EINVAL) return "Invalid sparse file format"; + if (err == -ENOMEM) return "Failed allocation while reading file"; + return android::base::StringPrintf("Unknown error %d", err); +} static void verbose_error(bool verbose, int err, const char *fmt, ...) { - char *s = ""; - char *at = ""; + if (!verbose) return; + + std::string msg = ErrorString(err); if (fmt) { + msg += " at "; va_list argp; - int size; - va_start(argp, fmt); - size = vsnprintf(NULL, 0, fmt, argp); + android::base::StringAppendV(&msg, fmt, argp); va_end(argp); - - if (size < 0) { - return; - } - - at = malloc(size + 1); - if (at == NULL) { - return; - } - - va_start(argp, fmt); - vsnprintf(at, size, fmt, argp); - va_end(argp); - at[size] = 0; - s = " at "; - } - if (verbose) { -#ifndef _WIN32 - if (err == -EOVERFLOW) { - sparse_print_verbose("EOF while reading file%s%s\n", s, at); - } else -#endif - if (err == -EINVAL) { - sparse_print_verbose("Invalid sparse file format%s%s\n", s, at); - } else if (err == -ENOMEM) { - sparse_print_verbose("Failed allocation while reading file%s%s\n", - s, at); - } else { - sparse_print_verbose("Unknown error %d%s%s\n", err, s, at); - } - } - if (fmt) { - free(at); } + sparse_print_verbose("%s\n", msg.c_str()); } static int process_raw_chunk(struct sparse_file *s, unsigned int chunk_size, @@ -104,7 +79,7 @@ static int process_raw_chunk(struct sparse_file *s, unsigned int chunk_size, { int ret; int chunk; - unsigned int len = blocks * s->block_size; + int64_t len = blocks * s->block_size; if (chunk_size % s->block_size != 0) { return -EINVAL; @@ -121,7 +96,7 @@ static int process_raw_chunk(struct sparse_file *s, unsigned int chunk_size, if (crc32) { while (len) { - chunk = min(len, COPY_BUF_SIZE); + chunk = std::min(len, COPY_BUF_SIZE); ret = read_all(fd, copybuf, chunk); if (ret < 0) { return ret; @@ -168,7 +143,7 @@ static int process_fill_chunk(struct sparse_file *s, unsigned int chunk_size, } while (len) { - chunk = min(len, COPY_BUF_SIZE); + chunk = std::min(len, COPY_BUF_SIZE); *crc32 = sparse_crc32(*crc32, copybuf, chunk); len -= chunk; } @@ -190,7 +165,7 @@ static int process_skip_chunk(struct sparse_file *s, unsigned int chunk_size, memset(copybuf, 0, COPY_BUF_SIZE); while (len) { - int chunk = min(len, COPY_BUF_SIZE); + int chunk = std::min(len, COPY_BUF_SIZE); *crc32 = sparse_crc32(*crc32, copybuf, chunk); len -= chunk; } @@ -284,7 +259,7 @@ static int sparse_file_read_sparse(struct sparse_file *s, int fd, bool crc) off64_t offset; if (!copybuf) { - copybuf = malloc(COPY_BUF_SIZE); + copybuf = (char *)malloc(COPY_BUF_SIZE); } if (!copybuf) { @@ -357,7 +332,7 @@ static int sparse_file_read_sparse(struct sparse_file *s, int fd, bool crc) static int sparse_file_read_normal(struct sparse_file *s, int fd) { int ret; - uint32_t *buf = malloc(s->block_size); + uint32_t *buf = (uint32_t *)malloc(s->block_size); unsigned int block = 0; int64_t remain = s->len; int64_t offset = 0; @@ -370,7 +345,7 @@ static int sparse_file_read_normal(struct sparse_file *s, int fd) } while (remain > 0) { - to_read = min(remain, s->block_size); + to_read = std::min(remain, (int64_t)(s->block_size)); ret = read_all(fd, buf, to_read); if (ret < 0) { error("failed to read sparse file");