Assert no divison by 0, correct superblocks 0 sequences case (#2592)

dev
sen 2021-05-07 13:26:56 -04:00 committed by GitHub
parent b4637d152a
commit 9e94b7cac5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 7 deletions

View File

@ -2418,8 +2418,9 @@ typedef struct {
} ZSTD_symbolEncodingTypeStats_t; } ZSTD_symbolEncodingTypeStats_t;
/* ZSTD_buildSequencesStatistics(): /* ZSTD_buildSequencesStatistics():
* Returns the size of the statistics for a given set of sequences, or a ZSTD error code, * Returns a ZSTD_symbolEncodingTypeStats_t, or a zstd error code in the `size` field.
* Also modifies LLtype, Offtype, MLtype, and lastNCount to the appropriate values. * Modifies `nextEntropy` to have the appropriate values as a side effect.
* nbSeq must be greater than 0.
* *
* entropyWkspSize must be of size at least ENTROPY_WORKSPACE_SIZE - (MaxSeq + 1)*sizeof(U32) * entropyWkspSize must be of size at least ENTROPY_WORKSPACE_SIZE - (MaxSeq + 1)*sizeof(U32)
*/ */
@ -2444,6 +2445,7 @@ ZSTD_buildSequencesStatistics(seqStore_t* seqStorePtr, size_t nbSeq,
/* convert length/distances into codes */ /* convert length/distances into codes */
ZSTD_seqToCodes(seqStorePtr); ZSTD_seqToCodes(seqStorePtr);
assert(op <= oend); assert(op <= oend);
assert(nbSeq != 0); /* ZSTD_selectEncodingType() divides by nbSeq */
/* build CTable for Literal Lengths */ /* build CTable for Literal Lengths */
{ unsigned max = MaxLL; { unsigned max = MaxLL;
size_t const mostFrequent = HIST_countFast_wksp(countWorkspace, &max, llCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */ size_t const mostFrequent = HIST_countFast_wksp(countWorkspace, &max, llCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */
@ -3121,6 +3123,20 @@ static size_t ZSTD_buildBlockEntropyStats_literals(void* const src, size_t srcSi
} }
} }
/* ZSTD_buildDummySequencesStatistics():
* Returns a ZSTD_symbolEncodingTypeStats_t with all encoding types as set_basic,
* and updates nextEntropy to the appropriate repeatMode.
*/
static ZSTD_symbolEncodingTypeStats_t
ZSTD_buildDummySequencesStatistics(ZSTD_fseCTables_t* nextEntropy) {
ZSTD_symbolEncodingTypeStats_t stats = {set_basic, set_basic, set_basic, 0, 0};
nextEntropy->litlength_repeatMode = FSE_repeat_none;
nextEntropy->offcode_repeatMode = FSE_repeat_none;
nextEntropy->matchlength_repeatMode = FSE_repeat_none;
return stats;
}
/** ZSTD_buildBlockEntropyStats_sequences() : /** ZSTD_buildBlockEntropyStats_sequences() :
* Builds entropy for the sequences. * Builds entropy for the sequences.
* Stores symbol compression modes and fse table to fseMetadata. * Stores symbol compression modes and fse table to fseMetadata.
@ -3144,10 +3160,11 @@ static size_t ZSTD_buildBlockEntropyStats_sequences(seqStore_t* seqStorePtr,
ZSTD_symbolEncodingTypeStats_t stats; ZSTD_symbolEncodingTypeStats_t stats;
DEBUGLOG(5, "ZSTD_buildBlockEntropyStats_sequences (nbSeq=%zu)", nbSeq); DEBUGLOG(5, "ZSTD_buildBlockEntropyStats_sequences (nbSeq=%zu)", nbSeq);
stats = ZSTD_buildSequencesStatistics(seqStorePtr, nbSeq, stats = nbSeq != 0 ? ZSTD_buildSequencesStatistics(seqStorePtr, nbSeq,
prevEntropy, nextEntropy, op, oend, prevEntropy, nextEntropy, op, oend,
strategy, countWorkspace, strategy, countWorkspace,
entropyWorkspace, entropyWorkspaceSize); entropyWorkspace, entropyWorkspaceSize)
: ZSTD_buildDummySequencesStatistics(nextEntropy);
FORWARD_IF_ERROR(stats.size, "ZSTD_buildSequencesStatistics failed!"); FORWARD_IF_ERROR(stats.size, "ZSTD_buildSequencesStatistics failed!");
fseMetadata->llType = (symbolEncodingType_e) stats.LLtype; fseMetadata->llType = (symbolEncodingType_e) stats.LLtype;
fseMetadata->ofType = (symbolEncodingType_e) stats.Offtype; fseMetadata->ofType = (symbolEncodingType_e) stats.Offtype;

View File

@ -85,6 +85,8 @@ static size_t ZSTD_entropyCost(unsigned const* count, unsigned const max, size_t
{ {
unsigned cost = 0; unsigned cost = 0;
unsigned s; unsigned s;
assert(total > 0);
for (s = 0; s <= max; ++s) { for (s = 0; s <= max; ++s) {
unsigned norm = (unsigned)((256 * count[s]) / total); unsigned norm = (unsigned)((256 * count[s]) / total);
if (count[s] != 0 && norm == 0) if (count[s] != 0 && norm == 0)

View File

@ -365,8 +365,9 @@ static size_t ZSTD_estimateSubBlockSize_sequences(const BYTE* ofCodeTable,
void* workspace, size_t wkspSize, void* workspace, size_t wkspSize,
int writeEntropy) int writeEntropy)
{ {
size_t sequencesSectionHeaderSize = 3; /* Use hard coded size of 3 bytes */ size_t const sequencesSectionHeaderSize = 3; /* Use hard coded size of 3 bytes */
size_t cSeqSizeEstimate = 0; size_t cSeqSizeEstimate = 0;
if (nbSeq == 0) return sequencesSectionHeaderSize;
cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, MaxOff, cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, MaxOff,
nbSeq, fseTables->offcodeCTable, NULL, nbSeq, fseTables->offcodeCTable, NULL,
OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,