Skip to content

Commit f52b850

Browse files
author
Alex A. Yermoshenko
committed
Merge branch 'master' into feature/libraryOfProcessedFiles
2 parents 17e0f33 + 66d25e4 commit f52b850

28 files changed

+11921
-7977
lines changed

.github/workflows/ci.yml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,13 @@ jobs:
99
strategy:
1010
matrix:
1111
os:
12-
- ubuntu-16.04
1312
- ubuntu-18.04
1413
- ubuntu-20.04
1514
- macos-10.15
1615
compiler:
1716
- { cc: gcc, cxx: g++ }
1817
- { cc: clang, cxx: clang++ }
1918

20-
exclude:
21-
# gcc 5 doesn't support C++17
22-
- os: ubuntu-16.04
23-
compiler: { cc: gcc, cxx: g++ }
24-
2519
fail-fast: false
2620

2721
env:

Leanify.vcxproj

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -321,11 +321,21 @@
321321
<ClCompile Include="formats\jpeg.cpp" />
322322
<ClCompile Include="formats\lua.cpp" />
323323
<ClCompile Include="formats\mime.cpp" />
324+
<ClCompile Include="formats\pe.cpp" />
325+
<ClCompile Include="formats\png.cpp" />
326+
<ClCompile Include="formats\rdb.cpp" />
327+
<ClCompile Include="formats\swf.cpp" />
328+
<ClCompile Include="formats\tar.cpp" />
324329
<ClCompile Include="formats\vcf.cpp" />
330+
<ClCompile Include="formats\xml.cpp" />
331+
<ClCompile Include="formats\zip.cpp" />
332+
<ClCompile Include="leanify.cpp" />
325333
<ClCompile Include="library.cpp" />
326334
<ClCompile Include="lib\LZMA\Alloc.c" />
335+
<ClCompile Include="lib\LZMA\CpuArch.c" />
327336
<ClCompile Include="lib\LZMA\LzFind.c" />
328337
<ClCompile Include="lib\LZMA\LzFindMt.c" />
338+
<ClCompile Include="lib\LZMA\LzFindOpt.c" />
329339
<ClCompile Include="lib\LZMA\LzmaDec.c" />
330340
<ClCompile Include="lib\LZMA\LzmaEnc.c" />
331341
<ClCompile Include="lib\LZMA\Threads.c" />
@@ -355,17 +365,7 @@
355365
<ClCompile Include="lib\mozjpeg\jmemnobs.c" />
356366
<ClCompile Include="lib\mozjpeg\jsimd_none.c" />
357367
<ClCompile Include="lib\mozjpeg\jutils.c" />
358-
<ClCompile Include="formats\pe.cpp" />
359-
<ClCompile Include="formats\png.cpp" />
360-
<ClCompile Include="formats\rdb.cpp" />
361-
<ClCompile Include="formats\swf.cpp" />
362-
<ClCompile Include="formats\tar.cpp" />
363368
<ClCompile Include="lib\pugixml\pugixml.cpp" />
364-
<ClCompile Include="formats\xml.cpp" />
365-
<ClCompile Include="formats\zip.cpp" />
366-
<ClCompile Include="lib\zopflipng\lodepng\lodepng.cpp" />
367-
<ClCompile Include="lib\zopflipng\lodepng\lodepng_util.cpp" />
368-
<ClCompile Include="lib\zopflipng\zopflipng_lib.cc" />
369369
<ClCompile Include="lib\zopfli\blocksplitter.c" />
370370
<ClCompile Include="lib\zopfli\cache.c" />
371371
<ClCompile Include="lib\zopfli\deflate.c" />
@@ -378,7 +378,9 @@
378378
<ClCompile Include="lib\zopfli\util.c" />
379379
<ClCompile Include="lib\zopfli\zlib_container.c" />
380380
<ClCompile Include="lib\zopfli\zopfli_lib.c" />
381-
<ClCompile Include="leanify.cpp" />
381+
<ClCompile Include="lib\zopflipng\lodepng\lodepng_util.cpp" />
382+
<ClCompile Include="lib\zopflipng\lodepng\lodepng.cpp" />
383+
<ClCompile Include="lib\zopflipng\zopflipng_lib.cc" />
382384
<ClCompile Include="main.cpp" />
383385
<ClCompile Include="utils.cpp" />
384386
</ItemGroup>

Makefile

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
LEANIFY_SRC := leanify.cpp main.cpp utils.cpp library.cpp $(wildcard formats/*.cpp)
2-
LZMA_OBJ := lib/LZMA/Alloc.o lib/LZMA/LzFind.o lib/LZMA/LzmaDec.o lib/LZMA/LzmaEnc.o
1+
LEANIFY_OBJ := leanify.o main.o utils.o library.o $(patsubst %.cpp,%.o,$(wildcard formats/*.cpp))
2+
LZMA_OBJ := lib/LZMA/Alloc.o lib/LZMA/LzFind.o lib/LZMA/LzFindMt.o lib/LZMA/LzFindOpt.o lib/LZMA/LzmaDec.o lib/LZMA/LzmaEnc.o lib/LZMA/Threads.o
33
MOZJPEG_OBJ := lib/mozjpeg/jaricom.o lib/mozjpeg/jcapimin.o lib/mozjpeg/jcarith.o lib/mozjpeg/jcext.o lib/mozjpeg/jchuff.o lib/mozjpeg/jcmarker.o lib/mozjpeg/jcmaster.o lib/mozjpeg/jcomapi.o lib/mozjpeg/jcparam.o lib/mozjpeg/jcphuff.o lib/mozjpeg/jctrans.o lib/mozjpeg/jdapimin.o lib/mozjpeg/jdarith.o lib/mozjpeg/jdatadst.o lib/mozjpeg/jdatasrc.o lib/mozjpeg/jdcoefct.o lib/mozjpeg/jdhuff.o lib/mozjpeg/jdinput.o lib/mozjpeg/jdmarker.o lib/mozjpeg/jdphuff.o lib/mozjpeg/jdtrans.o lib/mozjpeg/jerror.o lib/mozjpeg/jmemmgr.o lib/mozjpeg/jmemnobs.o lib/mozjpeg/jsimd_none.o lib/mozjpeg/jutils.o
44
PUGIXML_OBJ := lib/pugixml/pugixml.o
55
ZOPFLI_OBJ := lib/zopfli/hash.o lib/zopfli/squeeze.o lib/zopfli/gzip_container.o lib/zopfli/katajainen.o lib/zopfli/zopfli_lib.o lib/zopfli/cache.o lib/zopfli/zlib_container.o lib/zopfli/util.o lib/zopfli/tree.o lib/zopfli/deflate.o lib/zopfli/blocksplitter.o lib/zopfli/lz77.o
66
ZOPFLIPNG_OBJ := lib/zopflipng/lodepng/lodepng.o lib/zopflipng/lodepng/lodepng_util.o lib/zopflipng/zopflipng_lib.o
77

8-
CFLAGS += -Wall -Wextra -Wno-unused-parameter -Werror -O3 -msse2 -mfpmath=sse -flto
8+
CFLAGS += -Wall -Werror -O3 -msse2 -mfpmath=sse -flto
99
CPPFLAGS += -I./lib
1010
CXXFLAGS += $(CFLAGS) -std=c++17 -fno-rtti
1111
LDFLAGS += -flto -lpthread
@@ -17,11 +17,6 @@ else
1717
SYSTEM := $(shell uname -s)
1818
endif
1919

20-
# Gold linker only supports Linux
21-
ifeq ($(SYSTEM), Linux)
22-
LDFLAGS += -fuse-ld=gold
23-
endif
24-
2520
# -lstdc++fs supported only on Linux
2621
ifeq ($(SYSTEM), Linux)
2722
LDFLAGS += -lstdc++fs
@@ -34,25 +29,26 @@ else
3429
LDFLAGS += -s
3530
endif
3631

37-
# Multithread in LZMA SDK is only supported on Windows
3832
ifeq ($(SYSTEM), Windows)
39-
LEANIFY_SRC += fileio_win.cpp
40-
LZMA_OBJ += lib/LZMA/LzFindMt.o lib/LZMA/Threads.o
33+
LEANIFY_OBJ += fileio_win.o
4134
else
42-
LEANIFY_SRC += fileio_linux.cpp
43-
LZMA_CFLAGS := -D _7ZIP_ST
35+
LEANIFY_OBJ += fileio_linux.o
4436
endif
4537

46-
.PHONY: leanify clean
38+
.PHONY: leanify asan clean
4739

48-
leanify: $(LEANIFY_SRC) $(LZMA_OBJ) $(MOZJPEG_OBJ) $(PUGIXML_OBJ) $(ZOPFLI_OBJ) $(ZOPFLIPNG_OBJ)
49-
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $^ $(LDFLAGS) $(LDLIBS) -o $@
40+
leanify: $(LEANIFY_OBJ) $(LZMA_OBJ) $(MOZJPEG_OBJ) $(PUGIXML_OBJ) $(ZOPFLI_OBJ) $(ZOPFLIPNG_OBJ)
41+
$(CXX) $^ $(LDFLAGS) $(LDLIBS) -o $@
5042

51-
$(LZMA_OBJ): CFLAGS := $(filter-out -Wextra,$(CFLAGS)) $(LZMA_CFLAGS) -Wno-parentheses
43+
$(LEANIFY_OBJ): CFLAGS += -Wextra -Wno-unused-parameter
5244

53-
$(MOZJPEG_OBJ): CFLAGS := $(filter-out -Wextra,$(CFLAGS))
45+
$(LZMA_OBJ): CFLAGS += -Wno-unknown-warning-option -Wno-dangling-pointer
5446

5547
$(ZOPFLI_OBJ): CFLAGS += -Wno-unused-function
5648

49+
asan: CFLAGS += -g -fsanitize=address -fno-omit-frame-pointer
50+
asan: LDFLAGS := -fsanitize=address $(filter-out -s,$(LDFLAGS))
51+
asan: leanify
52+
5753
clean:
58-
rm -f $(LZMA_OBJ) $(MOZJPEG_OBJ) $(PUGIXML_OBJ) $(ZOPFLI_OBJ) $(ZOPFLIPNG_OBJ) leanify
54+
rm -f $(LEANIFY_OBJ) $(LZMA_OBJ) $(MOZJPEG_OBJ) $(PUGIXML_OBJ) $(ZOPFLI_OBJ) $(ZOPFLIPNG_OBJ) leanify

SECURITY.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Security Policy
2+
3+
## Reporting a Vulnerability
4+
5+
Please report security vulnerabilities to [email protected]

formats/rdb.cpp

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,28 @@ size_t Rdb::Leanify(size_t size_leanified /*= 0*/) {
2323
}
2424

2525
depth++;
26-
uint8_t* p_read;
26+
uint8_t* p_read = fp_;
2727
size_t rdb_size_leanified = 0;
2828

29-
// header
30-
p_read = fp_;
31-
fp_ -= size_leanified;
32-
3329
// total number of files including directory
3430
uint32_t file_num = *(uint32_t*)(p_read + 0x10);
3531

3632
uint64_t index_offset = *(uint64_t*)(p_read + 0x14);
3733

34+
if (index_offset > size_) {
35+
cerr << "index offset out of range: " << index_offset << endl;
36+
return Format::Leanify(size_leanified);
37+
}
38+
3839
uint64_t content_offset = index_offset + *(uint64_t*)(p_read + 0x1C);
3940

41+
if (content_offset < index_offset || content_offset > size_) {
42+
cerr << "content offset out of range: " << content_offset << endl;
43+
return Format::Leanify(size_leanified);
44+
}
45+
4046
// move header and indexes
47+
fp_ -= size_leanified;
4148
memmove(fp_, p_read, (size_t)content_offset);
4249

4350
uint8_t* p_index = fp_ + index_offset;
@@ -50,12 +57,26 @@ size_t Rdb::Leanify(size_t size_leanified /*= 0*/) {
5057
// note that on Linux wchar_t is 4 bytes instead of 2
5158
// so I can't use wcslen
5259
// p_index += (wcslen(file_name) + 1) * 2;
53-
while (*(uint16_t*)p_index) {
60+
while (p_index + 2 < fp_ + content_offset && *(uint16_t*)p_index) {
5461
p_index += 2;
5562
}
5663
p_index += 2;
5764

65+
size_t remaining_size = fp_ + size_leanified + size_ - p_read;
66+
if (p_index + 8 > fp_ + content_offset) {
67+
cerr << "index is overlapping with content" << endl;
68+
memmove(p_read - rdb_size_leanified - size_leanified, p_read, remaining_size);
69+
p_read += remaining_size;
70+
break;
71+
}
72+
5873
uint64_t file_size = *(uint64_t*)(p_index + 8);
74+
if (file_size > static_cast<uint64_t>(remaining_size)) {
75+
cerr << "file size out of range: " << file_size << endl;
76+
memmove(p_read - rdb_size_leanified - size_leanified, p_read, remaining_size);
77+
p_read += remaining_size;
78+
break;
79+
}
5980

6081
*(uint64_t*)p_index -= rdb_size_leanified;
6182

formats/swf.cpp

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ size_t GetRECTSize(uint8_t* rect) {
4141

4242
bool LZMACompress(const uint8_t* src, size_t src_len, vector<uint8_t>* out) {
4343
// Reserve enough space.
44-
out->resize(src_len + src_len / 8);
44+
out->resize(src_len + src_len / 8 + LZMA_PROPS_SIZE);
4545

4646
CLzmaEncProps props;
4747
LzmaEncProps_Init(&props);
@@ -81,8 +81,18 @@ size_t Swf::Leanify(size_t size_leanified /*= 0*/) {
8181
if (is_fast && compression != 'F')
8282
return Format::Leanify(size_leanified);
8383

84+
if (size_ < 8) {
85+
cerr << "SWF file too small!" << endl;
86+
return Format::Leanify(size_leanified);
87+
}
88+
8489
uint8_t* in_buffer = fp_ + 8;
85-
uint32_t in_len = *(uint32_t*)(fp_ + 4) - 8;
90+
uint32_t in_len = *(uint32_t*)(fp_ + 4);
91+
if (in_len < 9) {
92+
cerr << "invalid file size in header: " << in_len << endl;
93+
return Format::Leanify(size_leanified);
94+
}
95+
in_len -= 8;
8696

8797
// if SWF is compressed, decompress it first
8898
if (compression == 'C') {
@@ -101,6 +111,10 @@ size_t Swf::Leanify(size_t size_leanified /*= 0*/) {
101111
} else if (compression == 'Z') {
102112
// LZMA
103113
VerbosePrint("SWF is compressed with LZMA.");
114+
if (size_ < 4 + 12 + LZMA_PROPS_SIZE) {
115+
cerr << "SWF file too small!" << endl;
116+
return Format::Leanify(size_leanified);
117+
}
104118
// | 4 bytes | 4 bytes | 4 bytes | 5 bytes | n bytes | 6 bytes |
105119
// | 'ZWS' + version | scriptLen | compressedLen | LZMA props | LZMA data | LZMA end marker |
106120
uint8_t* dst_buffer = new uint8_t[in_len];
@@ -114,31 +128,50 @@ size_t Swf::Leanify(size_t size_leanified /*= 0*/) {
114128
in_buffer = dst_buffer;
115129
} else {
116130
VerbosePrint("SWF is not compressed.");
131+
if (in_len + 8 > size_) {
132+
cerr << "SWF file too small!" << endl;
133+
return Format::Leanify(size_leanified);
134+
}
117135
}
118136

119137
// parsing SWF tags
120138
uint8_t* p = in_buffer + GetRECTSize(in_buffer); // skip FrameSize which is a RECT
121139
p += 4; // skip FrameRate(2 Byte) + FrameCount(2 Byte) = 4 Byte
122140
size_t tag_size_leanified = 0;
123-
do {
141+
while (p + 2 <= in_buffer + in_len) {
124142
uint16_t tag_type = *(uint16_t*)p >> 6;
125143
uint32_t tag_length = *p & 0x3F;
126144
size_t tag_header_length = 2;
127145
if (tag_length == 0x3F) {
146+
if (p + 6 > in_buffer + in_len)
147+
break;
128148
tag_length = *(uint32_t*)(p + 2);
129149
tag_header_length += 4;
130150
}
131151

132152
memmove(p - tag_size_leanified, p, tag_header_length);
133153
p += tag_header_length;
134154

155+
if (tag_length > in_len || p - in_buffer + tag_length > in_len) {
156+
VerbosePrint("SWF tag too long: ", tag_length);
157+
break;
158+
}
159+
135160
switch (tag_type) {
136161
// DefineBitsLossless
137162
case 20:
138163
// DefineBitsLossless2
139164
case 36: {
140-
size_t header_size = 7 + (p[3] == 3);
141165
VerbosePrint("DefineBitsLossless tag found.");
166+
if (3 > tag_length) {
167+
VerbosePrint("SWF tag too short: ", tag_length);
168+
break;
169+
}
170+
size_t header_size = 7 + (p[3] == 3);
171+
if (header_size > tag_length) {
172+
VerbosePrint("SWF tag too short: ", tag_length);
173+
break;
174+
}
142175
memmove(p - tag_size_leanified, p, header_size);
143176

144177
// recompress Zlib bitmap data
@@ -151,6 +184,10 @@ size_t Swf::Leanify(size_t size_leanified /*= 0*/) {
151184
// DefineBitsJPEG2
152185
case 21: {
153186
VerbosePrint("DefineBitsJPEG2 tag found.");
187+
if (2 > tag_length) {
188+
VerbosePrint("SWF tag too short: ", tag_length);
189+
break;
190+
}
154191
// copy id
155192
*(uint16_t*)(p - tag_size_leanified) = *(uint16_t*)p;
156193

@@ -165,13 +202,21 @@ size_t Swf::Leanify(size_t size_leanified /*= 0*/) {
165202
case 35:
166203
// DefineBitsJPEG4
167204
case 90: {
205+
size_t header_size = tag_type == 90 ? 8 : 6;
206+
VerbosePrint("DefineBitsJPEG", header_size / 2, " tag found.");
207+
if (header_size > tag_length) {
208+
VerbosePrint("SWF tag too short: ", tag_length);
209+
break;
210+
}
168211
// copy id
169212
*(uint16_t*)(p - tag_size_leanified) = *(uint16_t*)p;
170213

171214
uint32_t img_size = *(uint32_t*)(p + 2);
172-
size_t header_size = tag_type == 90 ? 8 : 6;
215+
if (img_size > tag_length || header_size + img_size > tag_length) {
216+
VerbosePrint("SWF tag too short: ", tag_length);
217+
break;
218+
}
173219

174-
VerbosePrint("DefineBitsJPEG", header_size / 2, " tag found.");
175220
// Leanify embedded image
176221
size_t new_img_size = LeanifyFile(p + header_size, img_size, tag_size_leanified);
177222
*(uint32_t*)(p + 2 - tag_size_leanified) = new_img_size;
@@ -198,7 +243,7 @@ size_t Swf::Leanify(size_t size_leanified /*= 0*/) {
198243
memmove(p - tag_size_leanified, p, tag_length);
199244
}
200245
p += tag_length;
201-
} while (p < in_buffer + in_len);
246+
}
202247

203248
VerbosePrint("Uncompressed SWF tags leanified: ", tag_size_leanified);
204249
in_len -= tag_size_leanified;

0 commit comments

Comments
 (0)