@@ -220,6 +220,25 @@ static void HUF_setValue(HUF_CElt* elt, size_t value)
220
220
}
221
221
}
222
222
223
+ HUF_CTableHeader HUF_readCTableHeader (HUF_CElt const * ctable )
224
+ {
225
+ HUF_CTableHeader header ;
226
+ ZSTD_memcpy (& header , ctable , sizeof (header ));
227
+ return header ;
228
+ }
229
+
230
+ static void HUF_writeCTableHeader (HUF_CElt * ctable , U32 tableLog , U32 maxSymbolValue )
231
+ {
232
+ HUF_CTableHeader header ;
233
+ HUF_STATIC_ASSERT (sizeof (ctable [0 ]) == sizeof (header ));
234
+ ZSTD_memset (& header , 0 , sizeof (header ));
235
+ assert (tableLog < 256 );
236
+ header .tableLog = (BYTE )tableLog ;
237
+ assert (maxSymbolValue < 256 );
238
+ header .maxSymbolValue = (BYTE )maxSymbolValue ;
239
+ ZSTD_memcpy (ctable , & header , sizeof (header ));
240
+ }
241
+
223
242
typedef struct {
224
243
HUF_CompressWeightsWksp wksp ;
225
244
BYTE bitsToWeight [HUF_TABLELOG_MAX + 1 ]; /* precomputed conversion table */
@@ -237,6 +256,9 @@ size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize,
237
256
238
257
HUF_STATIC_ASSERT (HUF_CTABLE_WORKSPACE_SIZE >= sizeof (HUF_WriteCTableWksp ));
239
258
259
+ assert (HUF_readCTableHeader (CTable ).maxSymbolValue == maxSymbolValue );
260
+ assert (HUF_readCTableHeader (CTable ).tableLog == huffLog );
261
+
240
262
/* check conditions */
241
263
if (workspaceSize < sizeof (HUF_WriteCTableWksp )) return ERROR (GENERIC );
242
264
if (maxSymbolValue > HUF_SYMBOLVALUE_MAX ) return ERROR (maxSymbolValue_tooLarge );
@@ -283,7 +305,9 @@ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void
283
305
if (tableLog > HUF_TABLELOG_MAX ) return ERROR (tableLog_tooLarge );
284
306
if (nbSymbols > * maxSymbolValuePtr + 1 ) return ERROR (maxSymbolValue_tooSmall );
285
307
286
- CTable [0 ] = tableLog ;
308
+ * maxSymbolValuePtr = nbSymbols - 1 ;
309
+
310
+ HUF_writeCTableHeader (CTable , tableLog , * maxSymbolValuePtr );
287
311
288
312
/* Prepare base value per rank */
289
313
{ U32 n , nextRankStart = 0 ;
@@ -315,14 +339,15 @@ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void
315
339
{ U32 n ; for (n = 0 ; n < nbSymbols ; n ++ ) HUF_setValue (ct + n , valPerRank [HUF_getNbBits (ct [n ])]++ ); }
316
340
}
317
341
318
- * maxSymbolValuePtr = nbSymbols - 1 ;
319
342
return readSize ;
320
343
}
321
344
322
345
U32 HUF_getNbBitsFromCTable (HUF_CElt const * CTable , U32 symbolValue )
323
346
{
324
347
const HUF_CElt * const ct = CTable + 1 ;
325
348
assert (symbolValue <= HUF_SYMBOLVALUE_MAX );
349
+ if (symbolValue > HUF_readCTableHeader (CTable ).maxSymbolValue )
350
+ return 0 ;
326
351
return (U32 )HUF_getNbBits (ct [symbolValue ]);
327
352
}
328
353
@@ -723,7 +748,8 @@ static void HUF_buildCTableFromTree(HUF_CElt* CTable, nodeElt const* huffNode, i
723
748
HUF_setNbBits (ct + huffNode [n ].byte , huffNode [n ].nbBits ); /* push nbBits per symbol, symbol order */
724
749
for (n = 0 ; n < alphabetSize ; n ++ )
725
750
HUF_setValue (ct + n , valPerRank [HUF_getNbBits (ct [n ])]++ ); /* assign value within rank, symbol order */
726
- CTable [0 ] = maxNbBits ;
751
+
752
+ HUF_writeCTableHeader (CTable , maxNbBits , maxSymbolValue );
727
753
}
728
754
729
755
size_t
@@ -776,13 +802,20 @@ size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count,
776
802
}
777
803
778
804
int HUF_validateCTable (const HUF_CElt * CTable , const unsigned * count , unsigned maxSymbolValue ) {
779
- HUF_CElt const * ct = CTable + 1 ;
780
- int bad = 0 ;
781
- int s ;
782
- for (s = 0 ; s <= (int )maxSymbolValue ; ++ s ) {
783
- bad |= (count [s ] != 0 ) & (HUF_getNbBits (ct [s ]) == 0 );
784
- }
785
- return !bad ;
805
+ HUF_CTableHeader header = HUF_readCTableHeader (CTable );
806
+ HUF_CElt const * ct = CTable + 1 ;
807
+ int bad = 0 ;
808
+ int s ;
809
+
810
+ assert (header .tableLog <= HUF_TABLELOG_ABSOLUTEMAX );
811
+
812
+ if (header .maxSymbolValue < maxSymbolValue )
813
+ return 0 ;
814
+
815
+ for (s = 0 ; s <= (int )maxSymbolValue ; ++ s ) {
816
+ bad |= (count [s ] != 0 ) & (HUF_getNbBits (ct [s ]) == 0 );
817
+ }
818
+ return !bad ;
786
819
}
787
820
788
821
size_t HUF_compressBound (size_t size ) { return HUF_COMPRESSBOUND (size ); }
@@ -1024,7 +1057,7 @@ HUF_compress1X_usingCTable_internal_body(void* dst, size_t dstSize,
1024
1057
const void * src , size_t srcSize ,
1025
1058
const HUF_CElt * CTable )
1026
1059
{
1027
- U32 const tableLog = ( U32 ) CTable [ 0 ] ;
1060
+ U32 const tableLog = HUF_readCTableHeader ( CTable ). tableLog ;
1028
1061
HUF_CElt const * ct = CTable + 1 ;
1029
1062
const BYTE * ip = (const BYTE * ) src ;
1030
1063
BYTE * const ostart = (BYTE * )dst ;
@@ -1372,12 +1405,6 @@ HUF_compress_internal (void* dst, size_t dstSize,
1372
1405
huffLog = (U32 )maxBits ;
1373
1406
DEBUGLOG (6 , "bit distribution completed (%zu symbols)" , showCTableBits (table -> CTable + 1 , maxSymbolValue + 1 ));
1374
1407
}
1375
- /* Zero unused symbols in CTable, so we can check it for validity */
1376
- {
1377
- size_t const ctableSize = HUF_CTABLE_SIZE_ST (maxSymbolValue );
1378
- size_t const unusedSize = sizeof (table -> CTable ) - ctableSize * sizeof (HUF_CElt );
1379
- ZSTD_memset (table -> CTable + ctableSize , 0 , unusedSize );
1380
- }
1381
1408
1382
1409
/* Write table description header */
1383
1410
{ CHECK_V_F (hSize , HUF_writeCTable_wksp (op , dstSize , table -> CTable , maxSymbolValue , huffLog ,
0 commit comments