summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2017-03-09 05:51:27 +0300
committerAndrei Karas <akaras@inbox.ru>2017-03-09 05:51:27 +0300
commit5b2362d561714264681f99d4712f0b692be1c338 (patch)
tree7da719a8bcf438e044e1648a8ca3af8dc3c89a04
parent4d05e132cfd424e454d7ab3727775b127bf0e6a2 (diff)
downloadmanaplus-5b2362d561714264681f99d4712f0b692be1c338.tar.gz
manaplus-5b2362d561714264681f99d4712f0b692be1c338.tar.bz2
manaplus-5b2362d561714264681f99d4712f0b692be1c338.tar.xz
manaplus-5b2362d561714264681f99d4712f0b692be1c338.zip
Probably fix reading zip archives on big endian cpu.
-rw-r--r--src/fs/virtfs/zip.cpp27
1 files changed, 23 insertions, 4 deletions
diff --git a/src/fs/virtfs/zip.cpp b/src/fs/virtfs/zip.cpp
index 6d4f7e38a..7bfaba3fc 100644
--- a/src/fs/virtfs/zip.cpp
+++ b/src/fs/virtfs/zip.cpp
@@ -33,9 +33,18 @@
#include <iostream>
#include <unistd.h>
#include <zlib.h>
+#include <SDL_endian.h>
#include "debug.h"
+#ifndef SDL_BIG_ENDIAN
+#error missing SDL_endian.h
+#endif // SDL_BYTEORDER
+
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+#include <byteswap.h>
+#endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
+
// #define DEBUG_ZIP
extern const char *dirSeparator;
@@ -50,7 +59,15 @@ extern const char *dirSeparator;
delete [] buf; \
fclose(arcFile); \
return false; \
- } \
+ }
+
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+#define swapVal16(val) val = bswap_16(val);
+#define swapVal32(val) val = bswap_32(val);
+#else // SDL_BYTEORDER == SDL_BIG_ENDIAN
+#define swapVal16(val)
+#define swapVal32(val)
+#endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
namespace Zip
{
@@ -100,21 +117,22 @@ namespace Zip
// skip useless fields
fseek(arcFile, 4, SEEK_CUR); // + 4
// file header pointer on 8
- // +++ need add endian specific decoding for method
readVal(&method, 2, "compression method") // + 2
+ swapVal16(method)
header->compressed = (method != 0);
// file header pointer on 10
fseek(arcFile, 8, SEEK_CUR); // + 8
// file header pointer on 18
readVal(&header->compressSize, 4,
"zip compressed size") // + 4
+ swapVal32(header->compressSize)
// file header pointer on 22
- // +++ need add endian specific decoding for val32
readVal(&header->uncompressSize, 4,
"zip uncompressed size") // + 4
+ swapVal32(header->uncompressSize)
// file header pointer on 26
- // +++ need add endian specific decoding for val32
readVal(&val16, 2, "file name length") // + 2
+ swapVal16(val16)
// file header pointer on 28
const uint32_t fileNameLen = CAST_U32(val16);
if (fileNameLen > 1000)
@@ -127,6 +145,7 @@ namespace Zip
return false;
}
readVal(&val16, 2, "extra field length") // + 2
+ swapVal16(val16)
// file header pointer on 30
const uint32_t extraFieldLen = CAST_U32(val16);
readVal(buf, fileNameLen, "file name");