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
This commit is contained in:
parent
f836e69a7e
commit
894b354a52
142
lib/libarchive/archive_endian.h
Normal file
142
lib/libarchive/archive_endian.h
Normal file
@ -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
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user