diff options
author | des <des@FreeBSD.org> | 2008-01-03 18:30:37 +0000 |
---|---|---|
committer | des <des@FreeBSD.org> | 2008-01-03 18:30:37 +0000 |
commit | 894b354a523824007a685d7f0a2f8da95a55631d (patch) | |
tree | f9b9255efee47245fe632a604753a868baa6fa45 /lib/libarchive | |
parent | f836e69a7ed8e00a307d584a3919b53a6b67ce63 (diff) | |
download | FreeBSD-src-894b354a523824007a685d7f0a2f8da95a55631d.zip FreeBSD-src-894b354a523824007a685d7f0a2f8da95a55631d.tar.gz |
Crib {be,le}{16,32,64}{dec,enc} from src/sys/sys/endian.h and use it instead
of home-rolled [iu][248] in the ZIP support code.
Approved by: kientzle
Diffstat (limited to 'lib/libarchive')
-rw-r--r-- | lib/libarchive/archive_endian.h | 142 | ||||
-rw-r--r-- | lib/libarchive/archive_read_support_format_zip.c | 79 |
2 files changed, 164 insertions, 57 deletions
diff --git a/lib/libarchive/archive_endian.h b/lib/libarchive/archive_endian.h new file mode 100644 index 0000000..0df32d5 --- /dev/null +++ b/lib/libarchive/archive_endian.h @@ -0,0 +1,142 @@ +/*- + * Copyright (c) 2002 Thomas Moestl <tmm@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * + * Borrowed from FreeBSD's <sys/endian.h> + */ + +#ifndef ARCHIVE_ENDIAN_H_INCLUDED +#define ARCHIVE_ENDIAN_H_INCLUDED + +/* Alignment-agnostic encode/decode bytestream to/from little/big endian. */ + +static inline uint16_t +be16dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return ((p[0] << 8) | p[1]); +} + +static inline uint32_t +be32dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); +} + +static inline uint64_t +be64dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return (((uint64_t)be32dec(p) << 32) | be32dec(p + 4)); +} + +static inline uint16_t +le16dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return ((p[1] << 8) | p[0]); +} + +static inline uint32_t +le32dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); +} + +static inline uint64_t +le64dec(const void *pp) +{ + unsigned char const *p = (unsigned char const *)pp; + + return (((uint64_t)le32dec(p + 4) << 32) | le32dec(p)); +} + +static inline void +be16enc(void *pp, uint16_t u) +{ + unsigned char *p = (unsigned char *)pp; + + p[0] = (u >> 8) & 0xff; + p[1] = u & 0xff; +} + +static inline void +be32enc(void *pp, uint32_t u) +{ + unsigned char *p = (unsigned char *)pp; + + p[0] = (u >> 24) & 0xff; + p[1] = (u >> 16) & 0xff; + p[2] = (u >> 8) & 0xff; + p[3] = u & 0xff; +} + +static inline void +be64enc(void *pp, uint64_t u) +{ + unsigned char *p = (unsigned char *)pp; + + be32enc(p, u >> 32); + be32enc(p + 4, u & 0xffffffff); +} + +static inline void +le16enc(void *pp, uint16_t u) +{ + unsigned char *p = (unsigned char *)pp; + + p[0] = u & 0xff; + p[1] = (u >> 8) & 0xff; +} + +static inline void +le32enc(void *pp, uint32_t u) +{ + unsigned char *p = (unsigned char *)pp; + + p[0] = u & 0xff; + p[1] = (u >> 8) & 0xff; + p[2] = (u >> 16) & 0xff; + p[3] = (u >> 24) & 0xff; +} + +static inline void +le64enc(void *pp, uint64_t u) +{ + unsigned char *p = (unsigned char *)pp; + + le32enc(p, u & 0xffffffff); + le32enc(p + 4, u >> 32); +} + +#endif diff --git a/lib/libarchive/archive_read_support_format_zip.c b/lib/libarchive/archive_read_support_format_zip.c index 5e38ea2..24a689c 100644 --- a/lib/libarchive/archive_read_support_format_zip.c +++ b/lib/libarchive/archive_read_support_format_zip.c @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include "archive_entry.h" #include "archive_private.h" #include "archive_read_private.h" +#include "archive_endian.h" struct zip { /* entry_bytes_remaining is the number of bytes we expect. */ @@ -121,11 +122,6 @@ static int archive_read_format_zip_read_data(struct archive_read *, static int archive_read_format_zip_read_data_skip(struct archive_read *a); static int archive_read_format_zip_read_header(struct archive_read *, struct archive_entry *); -static int i2(const char *); -static int i4(const char *); -static unsigned int u2(const char *); -static unsigned int u4(const char *); -static uint64_t u8(const char *); static int zip_read_data_deflate(struct archive_read *a, const void **buff, size_t *size, off_t *offset); static int zip_read_data_none(struct archive_read *a, const void **buff, @@ -264,8 +260,8 @@ zip_read_file_header(struct archive_read *a, struct archive_entry *entry, zip->version = p->version[0]; zip->system = p->version[1]; - zip->flags = i2(p->flags); - zip->compression = i2(p->compression); + zip->flags = le16dec(p->flags); + zip->compression = le16dec(p->compression); if (zip->compression < sizeof(compression_names)/sizeof(compression_names[0])) zip->compression_name = compression_names[zip->compression]; @@ -277,11 +273,11 @@ zip_read_file_header(struct archive_read *a, struct archive_entry *entry, zip->mode = 0; zip->uid = 0; zip->gid = 0; - zip->crc32 = i4(p->crc32); - zip->filename_length = i2(p->filename_length); - zip->extra_length = i2(p->extra_length); - zip->uncompressed_size = u4(p->uncompressed_size); - zip->compressed_size = u4(p->compressed_size); + zip->crc32 = le32dec(p->crc32); + zip->filename_length = le16dec(p->filename_length); + zip->extra_length = le16dec(p->extra_length); + zip->uncompressed_size = le32dec(p->uncompressed_size); + zip->compressed_size = le32dec(p->compressed_size); (a->decompressor->consume)(a, sizeof(struct zip_file_header)); @@ -383,9 +379,9 @@ archive_read_format_zip_read_data(struct archive_read *a, "Truncated ZIP end-of-file record"); return (ARCHIVE_FATAL); } - zip->crc32 = i4(p + 4); - zip->compressed_size = u4(p + 8); - zip->uncompressed_size = u4(p + 12); + zip->crc32 = le32dec(p + 4); + zip->compressed_size = le32dec(p + 8); + zip->uncompressed_size = le32dec(p + 12); (a->decompressor->consume)(a, 16); } @@ -681,37 +677,6 @@ archive_read_format_zip_cleanup(struct archive_read *a) return (ARCHIVE_OK); } -static int -i2(const char *p) -{ - return ((0xff & (int)p[0]) + 256 * (0xff & (int)p[1])); -} - - -static int -i4(const char *p) -{ - return ((0xffff & i2(p)) + 0x10000 * (0xffff & i2(p+2))); -} - -static unsigned int -u2(const char *p) -{ - return ((0xff & (unsigned int)p[0]) + 256 * (0xff & (unsigned int)p[1])); -} - -static unsigned int -u4(const char *p) -{ - return u2(p) + 0x10000 * u2(p+2); -} - -static uint64_t -u8(const char *p) -{ - return u4(p) + 0x100000000LL * u4(p+4); -} - /* * The extra data is stored as a list of * id1+size1+data1 + id2+size2+data2 ... @@ -724,8 +689,8 @@ process_extra(const void* extra, struct zip* zip) const char *p = (const char *)extra; while (offset < zip->extra_length - 4) { - unsigned short headerid = u2(p + offset); - unsigned short datasize = u2(p + offset + 2); + unsigned short headerid = le16dec(p + offset); + unsigned short datasize = le16dec(p + offset + 2); offset += 4; if (offset + datasize > zip->extra_length) break; @@ -737,9 +702,9 @@ process_extra(const void* extra, struct zip* zip) case 0x0001: /* Zip64 extended information extra field. */ if (datasize >= 8) - zip->uncompressed_size = u8(p + offset); + zip->uncompressed_size = le64dec(p + offset); if (datasize >= 16) - zip->compressed_size = u8(p + offset + 8); + zip->compressed_size = le64dec(p + offset + 8); break; case 0x5455: { @@ -752,11 +717,11 @@ process_extra(const void* extra, struct zip* zip) { #ifdef DEBUG fprintf(stderr, "mtime: %lld -> %d\n", - (long long)zip->mtime, i4(p + offset)); + (long long)zip->mtime, le32dec(p + offset)); #endif if (datasize < 4) break; - zip->mtime = i4(p + offset); + zip->mtime = le32dec(p + offset); offset += 4; datasize -= 4; } @@ -764,7 +729,7 @@ process_extra(const void* extra, struct zip* zip) { if (datasize < 4) break; - zip->atime = i4(p + offset); + zip->atime = le32dec(p + offset); offset += 4; datasize -= 4; } @@ -772,7 +737,7 @@ process_extra(const void* extra, struct zip* zip) { if (datasize < 4) break; - zip->ctime = i4(p + offset); + zip->ctime = le32dec(p + offset); offset += 4; datasize -= 4; } @@ -782,12 +747,12 @@ process_extra(const void* extra, struct zip* zip) /* Info-ZIP Unix Extra Field (type 2) "Ux". */ #ifdef DEBUG fprintf(stderr, "uid %d gid %d\n", - i2(p + offset), i2(p + offset + 2)); + le16dec(p + offset), le16dec(p + offset + 2)); #endif if (datasize >= 2) - zip->uid = i2(p + offset); + zip->uid = le16dec(p + offset); if (datasize >= 4) - zip->gid = i2(p + offset + 2); + zip->gid = le16dec(p + offset + 2); break; default: break; |