@@ -41,7 +41,7 @@ size_t GetRECTSize(uint8_t* rect) {
4141
4242bool 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