- fixed some issues with m_swap's design.

The native byte order converters were defined as macros which hid some issues due to lack of type checks.
Additionally the ???Long variants taking 'long' variables were removed, because longs are not always 32 bits so this could be destructive.
As a result of this, removed several DWORDs from struct definitions in i_crash.cpp.
This commit is contained in:
Christoph Oelckers 2018-03-11 14:35:36 +01:00
parent 8bbfd39f42
commit 833dbee167
5 changed files with 104 additions and 86 deletions

View file

@ -264,7 +264,7 @@ bool M_AppendPNGText (FileWriter *file, const char *keyword, const char *text)
{ {
crc = AddCRC32 (crc, (uint8_t *)text, len); crc = AddCRC32 (crc, (uint8_t *)text, len);
} }
crc = BigLong((unsigned int)crc); crc = BigLong(crc);
return file->Write (&crc, 4) == 4; return file->Write (&crc, 4) == 4;
} }
return false; return false;

View file

@ -46,16 +46,6 @@ inline unsigned int LittleLong(unsigned int x)
return OSSwapLittleToHostInt32(x); return OSSwapLittleToHostInt32(x);
} }
inline int LittleLong(long x)
{
return OSSwapLittleToHostInt32((uint32_t)x);
}
inline unsigned int LittleLong(unsigned long x)
{
return OSSwapLittleToHostInt32((uint32_t)x);
}
inline short BigShort(short x) inline short BigShort(short x)
{ {
return (short)OSSwapBigToHostInt16((uint16_t)x); return (short)OSSwapBigToHostInt16((uint16_t)x);
@ -76,8 +66,7 @@ inline unsigned int BigLong(unsigned int x)
return OSSwapBigToHostInt32(x); return OSSwapBigToHostInt32(x);
} }
#else #elif defined __BIG_ENDIAN__
#ifdef __BIG_ENDIAN__
// Swap 16bit, that is, MSB and LSB byte. // Swap 16bit, that is, MSB and LSB byte.
// No masking with 0xFF should be necessary. // No masking with 0xFF should be necessary.
@ -120,42 +109,66 @@ inline int LittleLong (int x)
| (((unsigned int)x)<<24)); | (((unsigned int)x)<<24));
} }
inline unsigned int LittleLong(unsigned long x) inline short BigShort(short x)
{ {
return LittleLong((unsigned int)x); return x;
} }
inline int LittleLong(long x) inline unsigned short BigShort(unsigned short x)
{ {
return LittleLong((int)x); return x;
} }
#define BigShort(x) (x) inline unsigned int BigLong(unsigned int &x)
#define BigLong(x) (x) {
return x;
}
inline int BigLong(int &x)
{
return x;
}
#else #else
#define LittleShort(x) (x) inline short LittleShort(short x)
#define LittleLong(x) (x) {
return x;
}
#if defined(_MSC_VER) inline unsigned short LittleShort(unsigned short x)
{
return x;
}
inline short BigShort (short x) inline unsigned int LittleLong(unsigned int x)
{
return x;
}
inline int LittleLong(int x)
{
return x;
}
#ifdef _MSC_VER
inline short BigShort(short x)
{ {
return (short)_byteswap_ushort((unsigned short)x); return (short)_byteswap_ushort((unsigned short)x);
} }
inline unsigned short BigShort (unsigned short x) inline unsigned short BigShort(unsigned short x)
{ {
return _byteswap_ushort(x); return _byteswap_ushort(x);
} }
inline int BigLong (int x) inline int BigLong(int x)
{ {
return (int)_byteswap_ulong((unsigned long)x); return (int)_byteswap_ulong((unsigned long)x);
} }
inline unsigned int BigLong (unsigned int x) inline unsigned int BigLong(unsigned int x)
{ {
return (unsigned int)_byteswap_ulong((unsigned long)x); return (unsigned int)_byteswap_ulong((unsigned long)x);
} }
@ -190,10 +203,16 @@ inline int BigLong (int x)
| ((((unsigned int)x)<<8) & 0xff0000) | ((((unsigned int)x)<<8) & 0xff0000)
| (((unsigned int)x)<<24)); | (((unsigned int)x)<<24));
} }
#endif #endif
#endif // __BIG_ENDIAN__ #endif // __BIG_ENDIAN__
#endif // __APPLE__
// These may be destructive so they should create errors
unsigned long BigLong(unsigned long) = delete;
long BigLong(long) = delete;
unsigned long LittleLong(unsigned long) = delete;
long LittleLong(long) = delete;
// Data accessors, since some data is highly likely to be unaligned. // Data accessors, since some data is highly likely to be unaligned.
@ -206,10 +225,6 @@ inline int GetInt(const unsigned char *foo)
{ {
return *(const int *)foo; return *(const int *)foo;
} }
inline int GetBigInt(const unsigned char *foo)
{
return BigLong(GetInt(foo));
}
#else #else
inline int GetShort(const unsigned char *foo) inline int GetShort(const unsigned char *foo)
{ {
@ -219,11 +234,12 @@ inline int GetInt(const unsigned char *foo)
{ {
return int(foo[0] | (foo[1] << 8) | (foo[2] << 16) | (foo[3] << 24)); return int(foo[0] | (foo[1] << 8) | (foo[2] << 16) | (foo[3] << 24));
} }
#endif
inline int GetBigInt(const unsigned char *foo) inline int GetBigInt(const unsigned char *foo)
{ {
return int((foo[0] << 24) | (foo[1] << 16) | (foo[2] << 8) | foo[3]); return int((foo[0] << 24) | (foo[1] << 16) | (foo[2] << 8) | foo[3]);
} }
#endif
#ifdef __BIG_ENDIAN__ #ifdef __BIG_ENDIAN__
inline int GetNativeInt(const unsigned char *foo) inline int GetNativeInt(const unsigned char *foo)
{ {

View file

@ -507,17 +507,19 @@ FResourceFile *CheckZip(const char *filename, FileRdr &file, bool quiet)
// //
//========================================================================== //==========================================================================
static void time_to_dos(struct tm *time, unsigned short *dosdate, unsigned short *dostime) static std::pair<uint16_t, uint16_t> time_to_dos(struct tm *time)
{ {
std::pair<uint16_t, uint16_t> val;
if (time == NULL || time->tm_year < 80) if (time == NULL || time->tm_year < 80)
{ {
*dosdate = *dostime = 0; val.first = val.second = 0;
} }
else else
{ {
*dosdate = LittleShort((time->tm_year - 80) * 512 + (time->tm_mon + 1) * 32 + time->tm_mday); val.first = (time->tm_year - 80) * 512 + (time->tm_mon + 1) * 32 + time->tm_mday;
*dostime = LittleShort(time->tm_hour * 2048 + time->tm_min * 32 + time->tm_sec / 2); val.second= time->tm_hour * 2048 + time->tm_min * 32 + time->tm_sec / 2;
} }
return val;
} }
//========================================================================== //==========================================================================
@ -532,7 +534,7 @@ static void time_to_dos(struct tm *time, unsigned short *dosdate, unsigned short
// //
//========================================================================== //==========================================================================
int AppendToZip(FileWriter *zip_file, const char *filename, FCompressedBuffer &content, uint16_t date, uint16_t time) int AppendToZip(FileWriter *zip_file, const char *filename, FCompressedBuffer &content, std::pair<uint16_t, uint16_t> &dostime)
{ {
FZipLocalFileHeader local; FZipLocalFileHeader local;
int position; int position;
@ -540,10 +542,10 @@ int AppendToZip(FileWriter *zip_file, const char *filename, FCompressedBuffer &c
local.Magic = ZIP_LOCALFILE; local.Magic = ZIP_LOCALFILE;
local.VersionToExtract[0] = 20; local.VersionToExtract[0] = 20;
local.VersionToExtract[1] = 0; local.VersionToExtract[1] = 0;
local.Flags = content.mMethod == METHOD_DEFLATE ? LittleShort(2) : LittleShort((uint16_t)content.mZipFlags); local.Flags = content.mMethod == METHOD_DEFLATE ? LittleShort((uint16_t)2) : LittleShort((uint16_t)content.mZipFlags);
local.Method = LittleShort(content.mMethod); local.Method = LittleShort((uint16_t)content.mMethod);
local.ModDate = date; local.ModDate = LittleShort(dostime.first);
local.ModTime = time; local.ModTime = LittleShort(dostime.second);
local.CRC32 = content.mCRC32; local.CRC32 = content.mCRC32;
local.UncompressedSize = LittleLong(content.mSize); local.UncompressedSize = LittleLong(content.mSize);
local.CompressedSize = LittleLong(content.mCompressedSize); local.CompressedSize = LittleLong(content.mCompressedSize);
@ -573,7 +575,7 @@ int AppendToZip(FileWriter *zip_file, const char *filename, FCompressedBuffer &c
// //
//========================================================================== //==========================================================================
int AppendCentralDirectory(FileWriter *zip_file, const char *filename, FCompressedBuffer &content, uint16_t date, uint16_t time, int position) int AppendCentralDirectory(FileWriter *zip_file, const char *filename, FCompressedBuffer &content, std::pair<uint16_t, uint16_t> &dostime, int position)
{ {
FZipCentralDirectoryInfo dir; FZipCentralDirectoryInfo dir;
@ -582,10 +584,10 @@ int AppendCentralDirectory(FileWriter *zip_file, const char *filename, FCompress
dir.VersionMadeBy[1] = 0; dir.VersionMadeBy[1] = 0;
dir.VersionToExtract[0] = 20; dir.VersionToExtract[0] = 20;
dir.VersionToExtract[1] = 0; dir.VersionToExtract[1] = 0;
dir.Flags = content.mMethod == METHOD_DEFLATE ? LittleShort(2) : LittleShort((uint16_t)content.mZipFlags); dir.Flags = content.mMethod == METHOD_DEFLATE ? LittleShort((uint16_t)2) : LittleShort((uint16_t)content.mZipFlags);
dir.Method = LittleShort(content.mMethod); dir.Method = LittleShort((uint16_t)content.mMethod);
dir.ModTime = time; dir.ModTime = LittleShort(dostime.first);
dir.ModDate = date; dir.ModDate = LittleShort(dostime.second);
dir.CRC32 = content.mCRC32; dir.CRC32 = content.mCRC32;
dir.CompressedSize = LittleLong(content.mCompressedSize); dir.CompressedSize = LittleLong(content.mCompressedSize);
dir.UncompressedSize = LittleLong(content.mSize); dir.UncompressedSize = LittleLong(content.mSize);
@ -610,10 +612,9 @@ bool WriteZip(const char *filename, TArray<FString> &filenames, TArray<FCompress
// try to determine local time // try to determine local time
struct tm *ltime; struct tm *ltime;
time_t ttime; time_t ttime;
uint16_t mydate, mytime;
ttime = time(nullptr); ttime = time(nullptr);
ltime = localtime(&ttime); ltime = localtime(&ttime);
time_to_dos(ltime, &mydate, &mytime); auto dostime = time_to_dos(ltime);
TArray<int> positions; TArray<int> positions;
@ -624,7 +625,7 @@ bool WriteZip(const char *filename, TArray<FString> &filenames, TArray<FCompress
{ {
for (unsigned i = 0; i < filenames.Size(); i++) for (unsigned i = 0; i < filenames.Size(); i++)
{ {
int pos = AppendToZip(f, filenames[i], content[i], mydate, mytime); int pos = AppendToZip(f, filenames[i], content[i], dostime);
if (pos == -1) if (pos == -1)
{ {
delete f; delete f;
@ -637,7 +638,7 @@ bool WriteZip(const char *filename, TArray<FString> &filenames, TArray<FCompress
int dirofs = (int)f->Tell(); int dirofs = (int)f->Tell();
for (unsigned i = 0; i < filenames.Size(); i++) for (unsigned i = 0; i < filenames.Size(); i++)
{ {
if (AppendCentralDirectory(f, filenames[i], content[i], mydate, mytime, positions[i]) < 0) if (AppendCentralDirectory(f, filenames[i], content[i], dostime, positions[i]) < 0)
{ {
delete f; delete f;
remove(filename); remove(filename);
@ -650,9 +651,9 @@ bool WriteZip(const char *filename, TArray<FString> &filenames, TArray<FCompress
dirend.Magic = ZIP_ENDOFDIR; dirend.Magic = ZIP_ENDOFDIR;
dirend.DiskNumber = 0; dirend.DiskNumber = 0;
dirend.FirstDisk = 0; dirend.FirstDisk = 0;
dirend.NumEntriesOnAllDisks = dirend.NumEntries = LittleShort(filenames.Size()); dirend.NumEntriesOnAllDisks = dirend.NumEntries = LittleShort((uint16_t)filenames.Size());
dirend.DirectoryOffset = LittleLong(dirofs); dirend.DirectoryOffset = LittleLong(dirofs);
dirend.DirectorySize = LittleLong(f->Tell() - dirofs); dirend.DirectorySize = LittleLong((uint32_t)(f->Tell() - dirofs));
dirend.ZipCommentLength = 0; dirend.ZipCommentLength = 0;
if (f->Write(&dirend, sizeof(dirend)) != sizeof(dirend)) if (f->Write(&dirend, sizeof(dirend)) != sizeof(dirend))
{ {

View file

@ -106,18 +106,18 @@ MIDIWaveWriter::MIDIWaveWriter(const char *filename, SoftSynthMIDIDevice *playde
playDevice->CalcTickRate(); playDevice->CalcTickRate();
fmt.ChunkID = MAKE_ID('f','m','t',' '); fmt.ChunkID = MAKE_ID('f','m','t',' ');
fmt.ChunkLen = LittleLong(uint32_t(sizeof(fmt) - 8)); fmt.ChunkLen = LittleLong(uint32_t(sizeof(fmt) - 8));
fmt.FormatTag = LittleShort(0xFFFE); // WAVE_FORMAT_EXTENSIBLE fmt.FormatTag = LittleShort((uint16_t)0xFFFE); // WAVE_FORMAT_EXTENSIBLE
fmt.Channels = LittleShort(2); fmt.Channels = LittleShort((uint16_t)2);
fmt.SamplesPerSec = LittleLong(SampleRate); fmt.SamplesPerSec = LittleLong(SampleRate);
fmt.AvgBytesPerSec = LittleLong(SampleRate * 8); fmt.AvgBytesPerSec = LittleLong(SampleRate * 8);
fmt.BlockAlign = LittleShort(8); fmt.BlockAlign = LittleShort((uint16_t)8);
fmt.BitsPerSample = LittleShort(32); fmt.BitsPerSample = LittleShort((uint16_t)32);
fmt.ExtensionSize = LittleShort(2 + 4 + 16); fmt.ExtensionSize = LittleShort((uint16_t)(2 + 4 + 16));
fmt.ValidBitsPerSample = LittleShort(32); fmt.ValidBitsPerSample = LittleShort((uint16_t)32);
fmt.ChannelMask = LittleLong(3); fmt.ChannelMask = LittleLong(3);
fmt.SubFormatA = LittleLong(0x00000003); // Set subformat to KSDATAFORMAT_SUBTYPE_IEEE_FLOAT fmt.SubFormatA = LittleLong(0x00000003); // Set subformat to KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
fmt.SubFormatB = LittleShort(0x0000); fmt.SubFormatB = 0x0000;
fmt.SubFormatC = LittleShort(0x0010); fmt.SubFormatC = LittleShort((uint16_t)0x0010);
fmt.SubFormatD[0] = 0x80; fmt.SubFormatD[0] = 0x80;
fmt.SubFormatD[1] = 0x00; fmt.SubFormatD[1] = 0x00;
fmt.SubFormatD[2] = 0x00; fmt.SubFormatD[2] = 0x00;

View file

@ -166,49 +166,49 @@ namespace zip
#pragma pack(push,1) #pragma pack(push,1)
struct LocalFileHeader struct LocalFileHeader
{ {
DWORD Magic; // 0 uint32_t Magic; // 0
uint8_t VersionToExtract[2]; // 4 uint8_t VersionToExtract[2]; // 4
uint16_t Flags; // 6 uint16_t Flags; // 6
uint16_t Method; // 8 uint16_t Method; // 8
uint16_t ModTime; // 10 uint16_t ModTime; // 10
uint16_t ModDate; // 12 uint16_t ModDate; // 12
DWORD CRC32; // 14 uint32_t CRC32; // 14
DWORD CompressedSize; // 18 uint32_t CompressedSize; // 18
DWORD UncompressedSize; // 22 uint32_t UncompressedSize; // 22
uint16_t NameLength; // 26 uint16_t NameLength; // 26
uint16_t ExtraLength; // 28 uint16_t ExtraLength; // 28
}; };
struct CentralDirectoryEntry struct CentralDirectoryEntry
{ {
DWORD Magic; uint32_t Magic;
uint8_t VersionMadeBy[2]; uint8_t VersionMadeBy[2];
uint8_t VersionToExtract[2]; uint8_t VersionToExtract[2];
uint16_t Flags; uint16_t Flags;
uint16_t Method; uint16_t Method;
uint16_t ModTime; uint16_t ModTime;
uint16_t ModDate; uint16_t ModDate;
DWORD CRC32; uint32_t CRC32;
DWORD CompressedSize; uint32_t CompressedSize;
DWORD UncompressedSize; uint32_t UncompressedSize;
uint16_t NameLength; uint16_t NameLength;
uint16_t ExtraLength; uint16_t ExtraLength;
uint16_t CommentLength; uint16_t CommentLength;
uint16_t StartingDiskNumber; uint16_t StartingDiskNumber;
uint16_t InternalAttributes; uint16_t InternalAttributes;
DWORD ExternalAttributes; uint32_t ExternalAttributes;
DWORD LocalHeaderOffset; uint32_t LocalHeaderOffset;
}; };
struct EndOfCentralDirectory struct EndOfCentralDirectory
{ {
DWORD Magic; uint32_t Magic;
uint16_t DiskNumber; uint16_t DiskNumber;
uint16_t FirstDisk; uint16_t FirstDisk;
uint16_t NumEntries; uint16_t NumEntries;
uint16_t NumEntriesOnAllDisks; uint16_t NumEntriesOnAllDisks;
DWORD DirectorySize; uint32_t DirectorySize;
DWORD DirectoryOffset; uint32_t DirectoryOffset;
uint16_t ZipCommentLength; uint16_t ZipCommentLength;
}; };
#pragma pack(pop) #pragma pack(pop)
@ -219,9 +219,9 @@ struct TarFile
HANDLE File; HANDLE File;
const char *Filename; const char *Filename;
int ZipOffset; int ZipOffset;
DWORD UncompressedSize; uint32_t UncompressedSize;
DWORD CompressedSize; uint32_t CompressedSize;
DWORD CRC32; uint32_t CRC32;
bool Deflated; bool Deflated;
}; };
@ -1513,7 +1513,8 @@ static HANDLE MakeZip ()
struct tm *nowtm; struct tm *nowtm;
int i, numfiles; int i, numfiles;
HANDLE file; HANDLE file;
DWORD len, dirsize; DWORD len;
uint32_t dirsize;
size_t namelen; size_t namelen;
if (NumFiles == 0) if (NumFiles == 0)
@ -1553,7 +1554,7 @@ static HANDLE MakeZip ()
central.ModTime = dostime; central.ModTime = dostime;
central.ModDate = dosdate; central.ModDate = dosdate;
dirend.DirectoryOffset = LittleLong(SetFilePointer (file, 0, NULL, FILE_CURRENT)); dirend.DirectoryOffset = LittleLong((uint32_t)SetFilePointer (file, 0, NULL, FILE_CURRENT));
for (i = 0, numfiles = 0, dirsize = 0; i < NumFiles; ++i) for (i = 0, numfiles = 0, dirsize = 0; i < NumFiles; ++i)
{ {
@ -1565,8 +1566,8 @@ static HANDLE MakeZip ()
numfiles++; numfiles++;
if (TarFiles[i].Deflated) if (TarFiles[i].Deflated)
{ {
central.Flags = LittleShort(2); central.Flags = LittleShort((uint16_t)2);
central.Method = LittleShort(8); central.Method = LittleShort((uint16_t)8);
} }
else else
{ {
@ -1577,7 +1578,7 @@ static HANDLE MakeZip ()
central.InternalAttributes = 0; central.InternalAttributes = 0;
if (namelen > 4 && stricmp(TarFiles[i].Filename - 4, ".txt") == 0) if (namelen > 4 && stricmp(TarFiles[i].Filename - 4, ".txt") == 0)
{ // Bit 0 set indicates this is probably a text file. But do any tools use it? { // Bit 0 set indicates this is probably a text file. But do any tools use it?
central.InternalAttributes = LittleShort(1); central.InternalAttributes = LittleShort((uint16_t)1);
} }
central.CRC32 = LittleLong(TarFiles[i].CRC32); central.CRC32 = LittleLong(TarFiles[i].CRC32);
central.CompressedSize = LittleLong(TarFiles[i].CompressedSize); central.CompressedSize = LittleLong(TarFiles[i].CompressedSize);
@ -1590,7 +1591,7 @@ static HANDLE MakeZip ()
} }
// Write the directory terminator // Write the directory terminator
dirend.NumEntriesOnAllDisks = dirend.NumEntries = LittleShort(numfiles); dirend.NumEntriesOnAllDisks = dirend.NumEntries = LittleShort((uint16_t)numfiles);
dirend.DirectorySize = LittleLong(dirsize); dirend.DirectorySize = LittleLong(dirsize);
WriteFile (file, &dirend, sizeof(dirend), &len, NULL); WriteFile (file, &dirend, sizeof(dirend), &len, NULL);
@ -1635,7 +1636,7 @@ static void AddZipFile (HANDLE ziphandle, TarFile *whichfile, short dosdate, sho
if (gzip) if (gzip)
{ {
local.Method = LittleShort(8); local.Method = LittleShort((uint16_t)8);
whichfile->Deflated = true; whichfile->Deflated = true;
stream.next_out = outbuf; stream.next_out = outbuf;
stream.avail_out = sizeof(outbuf); stream.avail_out = sizeof(outbuf);
@ -1643,7 +1644,7 @@ static void AddZipFile (HANDLE ziphandle, TarFile *whichfile, short dosdate, sho
// Write out the header and filename. // Write out the header and filename.
local.VersionToExtract[0] = 20; local.VersionToExtract[0] = 20;
local.Flags = gzip ? LittleShort(2) : 0; local.Flags = gzip ? LittleShort((uint16_t)2) : 0;
local.ModTime = dostime; local.ModTime = dostime;
local.ModDate = dosdate; local.ModDate = dosdate;
local.UncompressedSize = LittleLong(whichfile->UncompressedSize); local.UncompressedSize = LittleLong(whichfile->UncompressedSize);