Skip to content

Commit 254b36a

Browse files
committed
* Enable Warnings-as-errors even on debug builds.
* Fix compilation on Linux if meta checks are enabled. * Fix output size being uninitialized in minlzdec * Rename Size dictionary variable to BufferSize * DtRepeatSymbol should also make sure that we're not going back to a distance beyond the beginning of the dictionary itself. * Fully and correctly support "GetSizeOnly" mode. Thanks to Daniel Martin for finding the issue. * Fix compile if meta checks are enabled. * Remove checking of dictionary size as it is not relevant to how the library works and actually breaks things. * Fix all W4 warnings on Windows
1 parent 2ee26ef commit 254b36a

9 files changed

Lines changed: 78 additions & 46 deletions

File tree

CMakeSettings.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,27 @@
5353
"wslPath": "${defaultWSLPath}",
5454
"addressSanitizerRuntimeFlags": "detect_leaks=0",
5555
"variables": []
56+
},
57+
{
58+
"name": "linux-amd64",
59+
"generator": "Ninja",
60+
"configurationType": "Debug",
61+
"cmakeExecutable": "/usr/bin/cmake",
62+
"remoteCopySourcesExclusionList": [ ".vs", ".git", "out" ],
63+
"cmakeCommandArgs": "",
64+
"buildCommandArgs": "",
65+
"ctestCommandArgs": "",
66+
"inheritEnvironments": [ "linux_clang_x64" ],
67+
"remoteMachineName": "888783467;172.18.4.234 (username=ionescu, port=22, authentication=Password)",
68+
"remoteCMakeListsRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/src",
69+
"remoteBuildRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/out/build/${name}",
70+
"remoteInstallRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/out/install/${name}",
71+
"remoteCopySources": true,
72+
"rsyncCommandArgs": "-t --delete --delete-excluded",
73+
"remoteCopyBuildOutput": false,
74+
"remoteCopySourcesMethod": "rsync",
75+
"addressSanitizerRuntimeFlags": "detect_leaks=0",
76+
"variables": []
5677
}
5778
]
5879
}

minlzdec/CMakeLists.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ target_link_libraries(minlzdec LINK_PUBLIC minlzlib)
66
if(MSVC)
77
set(CMAKE_C_STANDARD_LIBRARIES "")
88
set_property(TARGET minlzdec PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
9-
string(REGEX REPLACE "/W[1-3]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
10-
set(CMAKE_C_FLAGS_RELWITHDEBINFO "/WX /Ox /Ob2 /Oi /Ot /Oy /GF /Gy /MT /Zi /permissive-")
9+
string(REGEX REPLACE "/W[1-3]" "/W4 /WX" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
10+
set(CMAKE_C_FLAGS_RELWITHDEBINFO "/Ox /Ob2 /Oi /Ot /Oy /GF /Gy /MT /Zi /permissive-")
1111
set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "/OPT:ICF /OPT:REF /DEBUG /EMITPOGOPHASEINFO /NOVCFEATURE /NOCOFFGRPINFO /PDBALTPATH:minlzdec.pdb")
1212
else()
13-
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-Ofast -Wall -Werror")
13+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -Wno-multichar")
14+
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -Ofast -Wall -Werror")
1415
endif()

minlzdec/minlzdec.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ main (
6666
}
6767

6868
inputSize = (uint32_t)fileSize;
69+
outputSize = 0;
6970
decodeResult = XzDecode(inputBuffer, inputSize, outputBuffer, &outputSize);
7071
if (decodeResult == false)
7172
{

minlzlib/CMakeLists.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ if(MSVC)
1414
target_link_libraries(minlz)
1515
set_property(TARGET minlz_obj PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
1616
set_property(TARGET minlz PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
17-
string(REGEX REPLACE "/W[1-3]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
18-
set(CMAKE_C_FLAGS_RELWITHDEBINFO "/WX /Ox /Ob2 /Oi /Ot /Oy /GF /Gy /MT /Zi /wd4214 /permissive-")
17+
string(REGEX REPLACE "/W[1-3]" "/W4 /WX" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
18+
set(CMAKE_C_FLAGS_RELWITHDEBINFO "/Ox /Ob2 /Oi /Ot /Oy /GF /Gy /MT /Zi /wd4214 /permissive-")
1919
set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "/OPT:ICF /OPT:REF /NODEFAULTLIB /NOENTRY /DEBUG /EXPORT:XzDecode /EMITPOGOPHASEINFO /NOVCFEATURE /NOCOFFGRPINFO /DRIVER /MANIFEST:NO /PDBALTPATH:minlz.pdb /MERGE:.edata=.rdata")
2020
else()
21-
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-Ofast -Wall -Werror")
21+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -Wno-unknown-pragmas")
22+
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -Ofast -Wall -Werror")
2223
endif()

minlzlib/dictbuf.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ typedef struct _DICTIONARY_STATE
3737
// Buffer, start position, current position, and offset limit in the buffer
3838
//
3939
uint8_t* Buffer;
40+
uint32_t BufferSize;
4041
uint32_t Start;
4142
uint32_t Offset;
4243
uint32_t Limit;
43-
uint32_t Size;
4444
} DICTIONARY_STATE, *PDICTIONARY_STATE;
4545
DICTIONARY_STATE Dictionary;
4646

@@ -55,7 +55,7 @@ DtInitialize (
5555
//
5656
Dictionary.Buffer = HistoryBuffer;
5757
Dictionary.Offset = 0;
58-
Dictionary.Size = Size;
58+
Dictionary.BufferSize = Size;
5959
}
6060

6161
bool
@@ -67,7 +67,7 @@ DtSetLimit (
6767
// Make sure that the passed in dictionary limit fits within the size, and
6868
// then set this as the new limit. Save the starting point (current offset)
6969
//
70-
if ((Dictionary.Offset + Limit) > Dictionary.Size)
70+
if ((Dictionary.Offset + Limit) > Dictionary.BufferSize)
7171
{
7272
return false;
7373
}
@@ -107,7 +107,7 @@ DtGetSymbol (
107107
{
108108
//
109109
// If the dictionary is still empty, just return 0, otherwise, return the
110-
// symbol that is Distance bytes backward
110+
// symbol that is Distance bytes backward.
111111
//
112112
if (Distance > Dictionary.Offset)
113113
{
@@ -134,14 +134,19 @@ DtRepeatSymbol (
134134
)
135135
{
136136
//
137-
// Make sure we never get asked to write past the end of the dictionary,
138-
// then rewrite the stream of symbols forward into the dictionary
137+
// Make sure we never get asked to write past the end of the dictionary. We
138+
// should also not allow the distance to go beyond the current offset since
139+
// DtGetSymbol will return 0 thinking the dictionary is empty.
139140
//
140-
if ((Length + Dictionary.Offset) > Dictionary.Limit)
141+
if (((Length + Dictionary.Offset) > Dictionary.Limit) ||
142+
(Distance > Dictionary.Offset))
141143
{
142144
return false;
143145
}
144146

147+
//
148+
// Now rewrite the stream of past symbols forward into the dictionary.
149+
//
145150
do
146151
{
147152
DtPutSymbol(DtGetSymbol(Distance));

minlzlib/lzma2dec.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,12 @@ Lz2DecodeStream (
130130

131131
//
132132
// Decode the 1-based big-endian uncompressed size. It must fit into
133-
// the output buffer that was supplied.
133+
// the output buffer that was supplied, unless we're just getting size.
134134
//
135135
ChunkState.UncompressedSize = controlByte.u.Lzma.UncompressedSize << 16;
136136
ChunkState.UncompressedSize += (*pInfoBytes)[0] << 8;
137137
ChunkState.UncompressedSize += (*pInfoBytes)[1] + 1;
138-
if (!DtSetLimit(ChunkState.UncompressedSize))
138+
if (!GetSizeOnly && !DtSetLimit(ChunkState.UncompressedSize))
139139
{
140140
break;
141141
}
@@ -169,7 +169,7 @@ Lz2DecodeStream (
169169
//
170170
// Don't do any decompression if the caller only wants to know the size
171171
//
172-
if (GetSizeOnly != false)
172+
if (GetSizeOnly)
173173
{
174174
*BytesProcessed += ChunkState.UncompressedSize;
175175
BfSeek(ChunkState.CompressedSize, (uint8_t**)&pInfoBytes);

minlzlib/lzma2dec.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Module Name:
2323
--*/
2424

2525
#pragma once
26+
#pragma warning(disable:4214)
2627

2728
//
2829
// The most complex LZMA sequence possible is a "match" sequence where the

minlzlib/xzstream.c

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ Module Name:
3131
#include "minlzlib.h"
3232
#include "xzstream.h"
3333

34-
void __security_check_cookie(uintptr_t _StackCookie) { (void)(_StackCookie); }
34+
#ifdef _WIN32
35+
void __security_check_cookie(_In_ uintptr_t _StackCookie) { (void)(_StackCookie); }
36+
#endif
3537

3638
#ifdef MINLZ_META_CHECKS
3739
//
@@ -210,9 +212,9 @@ XzDecodeStreamFooter (
210212
//
211213
// Validate no flags other than checksum type are set
212214
//
213-
if ((streamFooter->Flags != 0) &&
214-
((streamFooter->CheckType != XzCheckTypeCrc32) &&
215-
(streamFooter->CheckType != XzCheckTypeNone)))
215+
if ((streamFooter->u.Flags != 0) &&
216+
((streamFooter->u.s.CheckType != XzCheckTypeCrc32) &&
217+
(streamFooter->u.s.CheckType != XzCheckTypeNone)))
216218
{
217219
return false;
218220
}
@@ -230,7 +232,7 @@ XzDecodeStreamFooter (
230232
//
231233
if (Crc32(&streamFooter->BackwardSize,
232234
sizeof(streamFooter->BackwardSize) +
233-
sizeof(streamFooter->Flags)) !=
235+
sizeof(streamFooter->u.Flags)) !=
234236
streamFooter->Crc32)
235237
{
236238
return false;
@@ -327,23 +329,23 @@ XzDecodeStreamHeader (
327329
//
328330
// Validate no flags other than checksum type are set
329331
//
330-
if ((streamHeader->Flags != 0) &&
331-
((streamHeader->CheckType != XzCheckTypeCrc32) &&
332-
(streamHeader->CheckType != XzCheckTypeNone)))
332+
if ((streamHeader->u.Flags != 0) &&
333+
((streamHeader->u.s.CheckType != XzCheckTypeCrc32) &&
334+
(streamHeader->u.s.CheckType != XzCheckTypeNone)))
333335
{
334336
return false;
335337
}
336338

337339
//
338340
// Remember that a checksum might come at the end of the block later
339341
//
340-
Container.ChecksumSize = streamHeader->CheckType * 4;
342+
Container.ChecksumSize = streamHeader->u.s.CheckType * 4;
341343
#endif
342344
#ifdef MINLZ_INTEGRITY_CHECKS
343345
//
344346
// Compute the header's CRC32 and make sure it's not corrupted
345347
//
346-
if (Crc32(&streamHeader->Flags, sizeof(streamHeader->Flags)) !=
348+
if (Crc32(&streamHeader->u.Flags, sizeof(streamHeader->u.Flags)) !=
347349
streamHeader->Crc32)
348350
{
349351
return false;
@@ -354,7 +356,7 @@ XzDecodeStreamHeader (
354356

355357
bool
356358
XzDecodeBlockHeader (
357-
uint32_t OutputSize
359+
void
358360
)
359361
{
360362
PXZ_BLOCK_HEADER blockHeader;
@@ -381,7 +383,7 @@ XzDecodeBlockHeader (
381383
//
382384
// Validate that no additional flags or filters are enabled
383385
//
384-
if (blockHeader->Flags != 0)
386+
if (blockHeader->u.Flags != 0)
385387
{
386388
return false;
387389
}
@@ -397,31 +399,29 @@ XzDecodeBlockHeader (
397399
//
398400
// With the expected number of property bytes
399401
//
400-
if (blockHeader->LzmaFlags.Size != sizeof(blockHeader->LzmaFlags.Properties))
402+
if (blockHeader->LzmaFlags.Size != sizeof(blockHeader->LzmaFlags.u.Properties))
401403
{
402404
return false;
403405
}
404406

405407
//
406-
// The only property is the dictionary size, make sure it is valid
408+
// The only property is the dictionary size, make sure it is valid.
407409
//
408-
size = blockHeader->LzmaFlags.DictionarySize;
409-
if (size > 39)
410-
{
411-
return false;
412-
}
413-
410+
// We don't actually need to store or compare the size with anything since
411+
// the library expects the caller to always put in a buffer that's large
412+
// enough to contain the full uncompressed file (or calling it in "get size
413+
// only" mode to get this information).
414414
//
415-
// And make sure it isn't larger than the output buffer
415+
// This output buffer can thus be smaller than the size of the dictionary
416+
// which is absolutely OK as long as that's actually the size of the output
417+
// file. If callers pass in a buffer size that's too small, decoding will
418+
// fail at later stages anyway, and that's incorrect use of minlzlib.
416419
//
417-
size = (2 + (size & 1)) << ((size >> 1) + 11);
418-
if (size > OutputSize)
420+
size = blockHeader->LzmaFlags.u.s.DictionarySize;
421+
if (size > 39)
419422
{
420423
return false;
421424
}
422-
#else
423-
(void)(OutputSize);
424-
#endif
425425
#ifdef MINLZ_INTEGRITY_CHECKS
426426
//
427427
// Compute the header's CRC32 and make sure it's not corrupted
@@ -432,6 +432,7 @@ XzDecodeBlockHeader (
432432
{
433433
return false;
434434
}
435+
#endif
435436
#endif
436437
return true;
437438
}
@@ -451,17 +452,17 @@ XzDecode (
451452
DtInitialize(OutputBuffer, *OutputSize);
452453

453454
//
454-
// Decode the stream header for validity
455+
// Decode the stream header for check for validity
455456
//
456457
if (!XzDecodeStreamHeader())
457458
{
458459
return false;
459460
}
460461

461462
//
462-
// Decode the block header to know the dictionary size
463+
// Decode the block header for check for validity
463464
//
464-
if (!XzDecodeBlockHeader(*OutputSize))
465+
if (!XzDecodeBlockHeader())
465466
{
466467
return false;
467468
}
@@ -470,7 +471,7 @@ XzDecode (
470471
// Decode the actual block
471472
//
472473
if (!XzDecodeBlock(OutputBuffer, OutputSize))
473-
{
474+
{
474475
return false;
475476
}
476477
#ifdef MINLZ_META_CHECKS

minlzlib/xzstream.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Module Name:
2424
--*/
2525

2626
#pragma once
27+
#pragma warning(disable:4214)
2728

2829
//
2930
// XZ streams encode certain numbers as "variable length integers", with 7 bits

0 commit comments

Comments
 (0)