@@ -1164,7 +1164,7 @@ void rans_set_cpu(int opts) {
1164
1164
unsigned char * rans_compress_to_4x16 (unsigned char * in , unsigned int in_size ,
1165
1165
unsigned char * out ,unsigned int * out_size ,
1166
1166
int order ) {
1167
- if (in_size > INT_MAX ) {
1167
+ if (in_size > INT_MAX || ( out && * out_size == 0 ) ) {
1168
1168
* out_size = 0 ;
1169
1169
return NULL ;
1170
1170
}
@@ -1199,6 +1199,12 @@ unsigned char *rans_compress_to_4x16(unsigned char *in, unsigned int in_size,
1199
1199
int N = (order >>8 ) & 0xff ;
1200
1200
if (N == 0 ) N = 4 ; // default for compatibility with old tests
1201
1201
1202
+ if (N > in_size )
1203
+ N = in_size ;
1204
+
1205
+ if (N > 255 )
1206
+ return NULL ;
1207
+
1202
1208
unsigned char * transposed = malloc (in_size );
1203
1209
unsigned int part_len [256 ];
1204
1210
unsigned int idx [256 ];
@@ -1249,26 +1255,31 @@ unsigned char *rans_compress_to_4x16(unsigned char *in, unsigned int in_size,
1249
1255
out2_start = out2 = out + 7 + 5 * N ; // shares a buffer with c_meta
1250
1256
for (i = 0 ; i < N ; i ++ ) {
1251
1257
// Brute force try all methods.
1252
- int j , m [] = {1 ,64 ,128 ,0 }, best_j = 0 , best_sz = in_size + 10 ;
1258
+ int j , m [] = {1 ,64 ,128 ,0 }, best_j = 0 , best_sz = INT_MAX ;
1253
1259
for (j = 0 ; j < sizeof (m )/sizeof (* m ); j ++ ) {
1254
1260
if ((order & m [j ]) != m [j ])
1255
1261
continue ;
1256
1262
1257
1263
// order-1 *only*; bit check above cannot elide order-0
1258
1264
if ((order & RANS_ORDER_STRIPE_NO0 ) && (m [j ]& 1 ) == 0 )
1259
1265
continue ;
1266
+
1267
+ if (out2 - out > * out_size )
1268
+ continue ; // an error, but caught in best_sz check later
1269
+
1260
1270
olen2 = * out_size - (out2 - out );
1261
1271
rans_compress_to_4x16 (transposed + idx [i ], part_len [i ],
1262
1272
out2 , & olen2 ,
1263
1273
m [j ] | RANS_ORDER_NOSZ
1264
1274
| (order & RANS_ORDER_X32 ));
1265
- if (best_sz > olen2 ) {
1275
+ if (olen2 && best_sz > olen2 ) {
1266
1276
best_sz = olen2 ;
1267
1277
best_j = j ;
1268
1278
if (j < sizeof (m )/sizeof (* m ) && olen2 > out_best_len ) {
1269
1279
unsigned char * tmp = realloc (out_best , olen2 );
1270
1280
if (!tmp ) {
1271
1281
free (out_free );
1282
+ free (transposed );
1272
1283
return NULL ;
1273
1284
}
1274
1285
out_best = tmp ;
@@ -1279,6 +1290,14 @@ unsigned char *rans_compress_to_4x16(unsigned char *in, unsigned int in_size,
1279
1290
memcpy (out_best , out2 , olen2 );
1280
1291
}
1281
1292
}
1293
+
1294
+ if (best_sz == INT_MAX ) {
1295
+ free (out_best );
1296
+ free (out_free );
1297
+ free (transposed );
1298
+ return NULL ;
1299
+ }
1300
+
1282
1301
if (best_j < sizeof (m )/sizeof (* m )) {
1283
1302
// Copy the best compression to output buffer if not current
1284
1303
memcpy (out2 , out_best , best_sz );
@@ -1301,6 +1320,9 @@ unsigned char *rans_compress_to_4x16(unsigned char *in, unsigned int in_size,
1301
1320
out [0 ] = RANS_ORDER_CAT ;
1302
1321
c_meta_len = 1 ;
1303
1322
c_meta_len += var_put_u32 (& out [1 ], out_end , in_size );
1323
+
1324
+ if (c_meta_len + in_size > * out_size )
1325
+ return NULL ;
1304
1326
if (in_size )
1305
1327
memcpy (out + c_meta_len , in , in_size );
1306
1328
* out_size = c_meta_len + in_size ;
@@ -1404,6 +1426,13 @@ unsigned char *rans_compress_to_4x16(unsigned char *in, unsigned int in_size,
1404
1426
out [0 ] &= ~RANS_ORDER_RLE ;
1405
1427
}
1406
1428
1429
+ if (c_meta_len > * out_size ) {
1430
+ free (rle );
1431
+ free (packed );
1432
+ * out_size = 0 ;
1433
+ return NULL ;
1434
+ }
1435
+
1407
1436
* out_size -= c_meta_len ;
1408
1437
if (order && in_size < 8 ) {
1409
1438
out [0 ] &= ~1 ;
@@ -1413,8 +1442,20 @@ unsigned char *rans_compress_to_4x16(unsigned char *in, unsigned int in_size,
1413
1442
rans_enc_func (do_simd , order )(in , in_size , out + c_meta_len , out_size );
1414
1443
1415
1444
if (* out_size >= in_size ) {
1445
+ if (out > out_end ) {
1446
+ free (rle );
1447
+ free (packed );
1448
+ return NULL ;
1449
+ }
1450
+
1416
1451
out [0 ] &= ~3 ;
1417
1452
out [0 ] |= RANS_ORDER_CAT | no_size ;
1453
+
1454
+ if (out + c_meta_len + in_size > out_end ) {
1455
+ free (rle );
1456
+ free (packed );
1457
+ return NULL ;
1458
+ }
1418
1459
if (in_size )
1419
1460
memcpy (out + c_meta_len , in , in_size );
1420
1461
* out_size = in_size ;
0 commit comments