zstd-ruby 1.4.0.0 → 1.4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/ext/zstdruby/libzstd/Makefile +5 -0
- data/ext/zstdruby/libzstd/common/compiler.h +7 -0
- data/ext/zstdruby/libzstd/common/zstd_internal.h +58 -6
- data/ext/zstdruby/libzstd/compress/zstd_compress.c +175 -117
- data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +74 -30
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +56 -36
- data/ext/zstdruby/libzstd/compress/zstd_fast.c +35 -14
- data/ext/zstdruby/libzstd/compress/zstd_lazy.c +10 -5
- data/ext/zstdruby/libzstd/compress/zstd_ldm.c +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_opt.c +45 -32
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +18 -7
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +1 -0
- data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +12 -9
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +20 -9
- data/ext/zstdruby/libzstd/dictBuilder/cover.c +154 -43
- data/ext/zstdruby/libzstd/dictBuilder/cover.h +38 -3
- data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +46 -39
- data/ext/zstdruby/libzstd/dictBuilder/zdict.c +9 -9
- data/ext/zstdruby/libzstd/dictBuilder/zdict.h +5 -0
- data/ext/zstdruby/libzstd/legacy/zstd_legacy.h +4 -0
- data/ext/zstdruby/libzstd/legacy/zstd_v01.c +95 -101
- data/ext/zstdruby/libzstd/legacy/zstd_v02.c +11 -6
- data/ext/zstdruby/libzstd/legacy/zstd_v03.c +11 -6
- data/ext/zstdruby/libzstd/legacy/zstd_v04.c +11 -8
- data/ext/zstdruby/libzstd/legacy/zstd_v05.c +88 -84
- data/ext/zstdruby/libzstd/legacy/zstd_v06.c +2 -4
- data/ext/zstdruby/libzstd/legacy/zstd_v07.c +2 -4
- data/ext/zstdruby/libzstd/zstd.h +53 -21
- data/lib/zstd-ruby/version.rb +1 -1
- metadata +3 -4
| @@ -33,13 +33,13 @@ extern "C" { | |
| 33 33 | 
             
            ***************************************/
         | 
| 34 34 | 
             
            #define kSearchStrength      8
         | 
| 35 35 | 
             
            #define HASH_READ_SIZE       8
         | 
| 36 | 
            -
            #define ZSTD_DUBT_UNSORTED_MARK 1   /* For btlazy2 strategy, index 1  | 
| 36 | 
            +
            #define ZSTD_DUBT_UNSORTED_MARK 1   /* For btlazy2 strategy, index ZSTD_DUBT_UNSORTED_MARK==1 means "unsorted".
         | 
| 37 37 | 
             
                                                   It could be confused for a real successor at index "1", if sorted as larger than its predecessor.
         | 
| 38 38 | 
             
                                                   It's not a big deal though : candidate will just be sorted again.
         | 
| 39 39 | 
             
                                                   Additionally, candidate position 1 will be lost.
         | 
| 40 40 | 
             
                                                   But candidate 1 cannot hide a large tree of candidates, so it's a minimal loss.
         | 
| 41 | 
            -
                                                   The benefit is that ZSTD_DUBT_UNSORTED_MARK cannot be mishandled after table re-use with a different strategy
         | 
| 42 | 
            -
                                                    | 
| 41 | 
            +
                                                   The benefit is that ZSTD_DUBT_UNSORTED_MARK cannot be mishandled after table re-use with a different strategy.
         | 
| 42 | 
            +
                                                   This constant is required by ZSTD_compressBlock_btlazy2() and ZSTD_reduceTable_internal() */
         | 
| 43 43 |  | 
| 44 44 |  | 
| 45 45 | 
             
            /*-*************************************
         | 
| @@ -128,21 +128,20 @@ typedef struct { | |
| 128 128 | 
             
                BYTE const* base;       /* All regular indexes relative to this position */
         | 
| 129 129 | 
             
                BYTE const* dictBase;   /* extDict indexes relative to this position */
         | 
| 130 130 | 
             
                U32 dictLimit;          /* below that point, need extDict */
         | 
| 131 | 
            -
                U32 lowLimit;           /* below that point, no more data */
         | 
| 131 | 
            +
                U32 lowLimit;           /* below that point, no more valid data */
         | 
| 132 132 | 
             
            } ZSTD_window_t;
         | 
| 133 133 |  | 
| 134 134 | 
             
            typedef struct ZSTD_matchState_t ZSTD_matchState_t;
         | 
| 135 135 | 
             
            struct ZSTD_matchState_t {
         | 
| 136 136 | 
             
                ZSTD_window_t window;   /* State for window round buffer management */
         | 
| 137 | 
            -
                U32 loadedDictEnd;      /* index of end of dictionary */
         | 
| 137 | 
            +
                U32 loadedDictEnd;      /* index of end of dictionary, within context's referential. When dict referential is copied into active context (i.e. not attached), effectively same value as dictSize, since referential starts from zero */
         | 
| 138 138 | 
             
                U32 nextToUpdate;       /* index from which to continue table update */
         | 
| 139 | 
            -
                U32 nextToUpdate3;      /* index from which to continue table update */
         | 
| 140 139 | 
             
                U32 hashLog3;           /* dispatch table : larger == faster, more memory */
         | 
| 141 140 | 
             
                U32* hashTable;
         | 
| 142 141 | 
             
                U32* hashTable3;
         | 
| 143 142 | 
             
                U32* chainTable;
         | 
| 144 143 | 
             
                optState_t opt;         /* optimal parser state */
         | 
| 145 | 
            -
                const ZSTD_matchState_t | 
| 144 | 
            +
                const ZSTD_matchState_t* dictMatchState;
         | 
| 146 145 | 
             
                ZSTD_compressionParameters cParams;
         | 
| 147 146 | 
             
            };
         | 
| 148 147 |  | 
| @@ -195,6 +194,9 @@ struct ZSTD_CCtx_params_s { | |
| 195 194 | 
             
                int compressionLevel;
         | 
| 196 195 | 
             
                int forceWindow;           /* force back-references to respect limit of
         | 
| 197 196 | 
             
                                            * 1<<wLog, even for dictionary */
         | 
| 197 | 
            +
                size_t targetCBlockSize;   /* Tries to fit compressed block size to be around targetCBlockSize.
         | 
| 198 | 
            +
                                            * No target when targetCBlockSize == 0.
         | 
| 199 | 
            +
                                            * There is no guarantee on compressed block size */
         | 
| 198 200 |  | 
| 199 201 | 
             
                ZSTD_dictAttachPref_e attachDictPref;
         | 
| 200 202 | 
             
                ZSTD_literalCompressionMode_e literalCompressionMode;
         | 
| @@ -324,7 +326,7 @@ MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const v | |
| 324 326 | 
             
                /* copy Literals */
         | 
| 325 327 | 
             
                assert(seqStorePtr->maxNbLit <= 128 KB);
         | 
| 326 328 | 
             
                assert(seqStorePtr->lit + litLength <= seqStorePtr->litStart + seqStorePtr->maxNbLit);
         | 
| 327 | 
            -
                ZSTD_wildcopy(seqStorePtr->lit, literals, litLength);
         | 
| 329 | 
            +
                ZSTD_wildcopy(seqStorePtr->lit, literals, litLength, ZSTD_no_overlap);
         | 
| 328 330 | 
             
                seqStorePtr->lit += litLength;
         | 
| 329 331 |  | 
| 330 332 | 
             
                /* literal Length */
         | 
| @@ -564,6 +566,9 @@ MEM_STATIC U64 ZSTD_rollingHash_rotate(U64 hash, BYTE toRemove, BYTE toAdd, U64 | |
| 564 566 | 
             
            /*-*************************************
         | 
| 565 567 | 
             
            *  Round buffer management
         | 
| 566 568 | 
             
            ***************************************/
         | 
| 569 | 
            +
            #if (ZSTD_WINDOWLOG_MAX_64 > 31)
         | 
| 570 | 
            +
            # error "ZSTD_WINDOWLOG_MAX is too large : would overflow ZSTD_CURRENT_MAX"
         | 
| 571 | 
            +
            #endif
         | 
| 567 572 | 
             
            /* Max current allowed */
         | 
| 568 573 | 
             
            #define ZSTD_CURRENT_MAX ((3U << 29) + (1U << ZSTD_WINDOWLOG_MAX))
         | 
| 569 574 | 
             
            /* Maximum chunk size before overflow correction needs to be called again */
         | 
| @@ -675,31 +680,49 @@ MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog, | |
| 675 680 | 
             
             * Updates lowLimit so that:
         | 
| 676 681 | 
             
             *    (srcEnd - base) - lowLimit == maxDist + loadedDictEnd
         | 
| 677 682 | 
             
             *
         | 
| 678 | 
            -
             *  | 
| 679 | 
            -
             * This must be called before a block compression call | 
| 680 | 
            -
             * | 
| 683 | 
            +
             * It ensures index is valid as long as index >= lowLimit.
         | 
| 684 | 
            +
             * This must be called before a block compression call.
         | 
| 685 | 
            +
             *
         | 
| 686 | 
            +
             * loadedDictEnd is only defined if a dictionary is in use for current compression.
         | 
| 687 | 
            +
             * As the name implies, loadedDictEnd represents the index at end of dictionary.
         | 
| 688 | 
            +
             * The value lies within context's referential, it can be directly compared to blockEndIdx.
         | 
| 681 689 | 
             
             *
         | 
| 682 | 
            -
             * If loadedDictEndPtr is  | 
| 683 | 
            -
             *  | 
| 684 | 
            -
             *  | 
| 685 | 
            -
             *  | 
| 686 | 
            -
             *  | 
| 690 | 
            +
             * If loadedDictEndPtr is NULL, no dictionary is in use, and we use loadedDictEnd == 0.
         | 
| 691 | 
            +
             * If loadedDictEndPtr is not NULL, we set it to zero after updating lowLimit.
         | 
| 692 | 
            +
             * This is because dictionaries are allowed to be referenced fully
         | 
| 693 | 
            +
             * as long as the last byte of the dictionary is in the window.
         | 
| 694 | 
            +
             * Once input has progressed beyond window size, dictionary cannot be referenced anymore.
         | 
| 687 695 | 
             
             *
         | 
| 688 | 
            -
             * In normal dict mode, the  | 
| 689 | 
            -
             * dictMatchState mode, lowLimit and dictLimit are the same, | 
| 690 | 
            -
             * is below them. | 
| 696 | 
            +
             * In normal dict mode, the dictionary lies between lowLimit and dictLimit.
         | 
| 697 | 
            +
             * In dictMatchState mode, lowLimit and dictLimit are the same,
         | 
| 698 | 
            +
             * and the dictionary is below them.
         | 
| 699 | 
            +
             * forceWindow and dictMatchState are therefore incompatible.
         | 
| 691 700 | 
             
             */
         | 
| 692 701 | 
             
            MEM_STATIC void
         | 
| 693 702 | 
             
            ZSTD_window_enforceMaxDist(ZSTD_window_t* window,
         | 
| 694 | 
            -
             | 
| 695 | 
            -
                                       U32 | 
| 696 | 
            -
                                       U32* | 
| 703 | 
            +
                                 const void* blockEnd,
         | 
| 704 | 
            +
                                       U32   maxDist,
         | 
| 705 | 
            +
                                       U32*  loadedDictEndPtr,
         | 
| 697 706 | 
             
                                 const ZSTD_matchState_t** dictMatchStatePtr)
         | 
| 698 707 | 
             
            {
         | 
| 699 | 
            -
                U32 const blockEndIdx = (U32)((BYTE const*) | 
| 700 | 
            -
                U32 loadedDictEnd = (loadedDictEndPtr != NULL) ? *loadedDictEndPtr : 0;
         | 
| 701 | 
            -
                DEBUGLOG(5, "ZSTD_window_enforceMaxDist: blockEndIdx=%u, maxDist=%u",
         | 
| 702 | 
            -
                            (unsigned)blockEndIdx, (unsigned)maxDist);
         | 
| 708 | 
            +
                U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base);
         | 
| 709 | 
            +
                U32 const loadedDictEnd = (loadedDictEndPtr != NULL) ? *loadedDictEndPtr : 0;
         | 
| 710 | 
            +
                DEBUGLOG(5, "ZSTD_window_enforceMaxDist: blockEndIdx=%u, maxDist=%u, loadedDictEnd=%u",
         | 
| 711 | 
            +
                            (unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd);
         | 
| 712 | 
            +
             | 
| 713 | 
            +
                /* - When there is no dictionary : loadedDictEnd == 0.
         | 
| 714 | 
            +
                     In which case, the test (blockEndIdx > maxDist) is merely to avoid
         | 
| 715 | 
            +
                     overflowing next operation `newLowLimit = blockEndIdx - maxDist`.
         | 
| 716 | 
            +
                   - When there is a standard dictionary :
         | 
| 717 | 
            +
                     Index referential is copied from the dictionary,
         | 
| 718 | 
            +
                     which means it starts from 0.
         | 
| 719 | 
            +
                     In which case, loadedDictEnd == dictSize,
         | 
| 720 | 
            +
                     and it makes sense to compare `blockEndIdx > maxDist + dictSize`
         | 
| 721 | 
            +
                     since `blockEndIdx` also starts from zero.
         | 
| 722 | 
            +
                   - When there is an attached dictionary :
         | 
| 723 | 
            +
                     loadedDictEnd is expressed within the referential of the context,
         | 
| 724 | 
            +
                     so it can be directly compared against blockEndIdx.
         | 
| 725 | 
            +
                */
         | 
| 703 726 | 
             
                if (blockEndIdx > maxDist + loadedDictEnd) {
         | 
| 704 727 | 
             
                    U32 const newLowLimit = blockEndIdx - maxDist;
         | 
| 705 728 | 
             
                    if (window->lowLimit < newLowLimit) window->lowLimit = newLowLimit;
         | 
| @@ -708,10 +731,31 @@ ZSTD_window_enforceMaxDist(ZSTD_window_t* window, | |
| 708 731 | 
             
                                    (unsigned)window->dictLimit, (unsigned)window->lowLimit);
         | 
| 709 732 | 
             
                        window->dictLimit = window->lowLimit;
         | 
| 710 733 | 
             
                    }
         | 
| 711 | 
            -
                     | 
| 712 | 
            -
             | 
| 713 | 
            -
                    if (dictMatchStatePtr)
         | 
| 714 | 
            -
             | 
| 734 | 
            +
                    /* On reaching window size, dictionaries are invalidated */
         | 
| 735 | 
            +
                    if (loadedDictEndPtr) *loadedDictEndPtr = 0;
         | 
| 736 | 
            +
                    if (dictMatchStatePtr) *dictMatchStatePtr = NULL;
         | 
| 737 | 
            +
                }
         | 
| 738 | 
            +
            }
         | 
| 739 | 
            +
             | 
| 740 | 
            +
            /* Similar to ZSTD_window_enforceMaxDist(),
         | 
| 741 | 
            +
             * but only invalidates dictionary
         | 
| 742 | 
            +
             * when input progresses beyond window size. */
         | 
| 743 | 
            +
            MEM_STATIC void
         | 
| 744 | 
            +
            ZSTD_checkDictValidity(ZSTD_window_t* window,
         | 
| 745 | 
            +
                                   const void* blockEnd,
         | 
| 746 | 
            +
                                         U32   maxDist,
         | 
| 747 | 
            +
                                         U32*  loadedDictEndPtr,
         | 
| 748 | 
            +
                                   const ZSTD_matchState_t** dictMatchStatePtr)
         | 
| 749 | 
            +
            {
         | 
| 750 | 
            +
                U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base);
         | 
| 751 | 
            +
                U32 const loadedDictEnd = (loadedDictEndPtr != NULL) ? *loadedDictEndPtr : 0;
         | 
| 752 | 
            +
                DEBUGLOG(5, "ZSTD_checkDictValidity: blockEndIdx=%u, maxDist=%u, loadedDictEnd=%u",
         | 
| 753 | 
            +
                            (unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd);
         | 
| 754 | 
            +
             | 
| 755 | 
            +
                if (loadedDictEnd && (blockEndIdx > maxDist + loadedDictEnd)) {
         | 
| 756 | 
            +
                    /* On reaching window size, dictionaries are invalidated */
         | 
| 757 | 
            +
                    if (loadedDictEndPtr) *loadedDictEndPtr = 0;
         | 
| 758 | 
            +
                    if (dictMatchStatePtr) *dictMatchStatePtr = NULL;
         | 
| 715 759 | 
             
                }
         | 
| 716 760 | 
             
            }
         | 
| 717 761 |  | 
| @@ -43,8 +43,7 @@ void ZSTD_fillDoubleHashTable(ZSTD_matchState_t* ms, | |
| 43 43 | 
             
                        /* Only load extra positions for ZSTD_dtlm_full */
         | 
| 44 44 | 
             
                        if (dtlm == ZSTD_dtlm_fast)
         | 
| 45 45 | 
             
                            break;
         | 
| 46 | 
            -
             | 
| 47 | 
            -
                }
         | 
| 46 | 
            +
                }   }
         | 
| 48 47 | 
             
            }
         | 
| 49 48 |  | 
| 50 49 |  | 
| @@ -63,7 +62,10 @@ size_t ZSTD_compressBlock_doubleFast_generic( | |
| 63 62 | 
             
                const BYTE* const istart = (const BYTE*)src;
         | 
| 64 63 | 
             
                const BYTE* ip = istart;
         | 
| 65 64 | 
             
                const BYTE* anchor = istart;
         | 
| 66 | 
            -
                const U32  | 
| 65 | 
            +
                const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);
         | 
| 66 | 
            +
                const U32 lowestValid = ms->window.dictLimit;
         | 
| 67 | 
            +
                const U32 maxDistance = 1U << cParams->windowLog;
         | 
| 68 | 
            +
                const U32 prefixLowestIndex = (endIndex - lowestValid > maxDistance) ? endIndex - maxDistance : lowestValid;
         | 
| 67 69 | 
             
                const BYTE* const prefixLowest = base + prefixLowestIndex;
         | 
| 68 70 | 
             
                const BYTE* const iend = istart + srcSize;
         | 
| 69 71 | 
             
                const BYTE* const ilimit = iend - HASH_READ_SIZE;
         | 
| @@ -95,8 +97,15 @@ size_t ZSTD_compressBlock_doubleFast_generic( | |
| 95 97 | 
             
                                                 dictCParams->chainLog : hBitsS;
         | 
| 96 98 | 
             
                const U32 dictAndPrefixLength  = (U32)(ip - prefixLowest + dictEnd - dictStart);
         | 
| 97 99 |  | 
| 100 | 
            +
                DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_generic");
         | 
| 101 | 
            +
             | 
| 98 102 | 
             
                assert(dictMode == ZSTD_noDict || dictMode == ZSTD_dictMatchState);
         | 
| 99 103 |  | 
| 104 | 
            +
                /* if a dictionary is attached, it must be within window range */
         | 
| 105 | 
            +
                if (dictMode == ZSTD_dictMatchState) {
         | 
| 106 | 
            +
                    assert(lowestValid + maxDistance >= endIndex);
         | 
| 107 | 
            +
                }
         | 
| 108 | 
            +
             | 
| 100 109 | 
             
                /* init */
         | 
| 101 110 | 
             
                ip += (dictAndPrefixLength == 0);
         | 
| 102 111 | 
             
                if (dictMode == ZSTD_noDict) {
         | 
| @@ -138,7 +147,7 @@ size_t ZSTD_compressBlock_doubleFast_generic( | |
| 138 147 | 
             
                        const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend;
         | 
| 139 148 | 
             
                        mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4;
         | 
| 140 149 | 
             
                        ip++;
         | 
| 141 | 
            -
                        ZSTD_storeSeq(seqStore, ip-anchor, anchor, 0, mLength-MINMATCH);
         | 
| 150 | 
            +
                        ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, 0, mLength-MINMATCH);
         | 
| 142 151 | 
             
                        goto _match_stored;
         | 
| 143 152 | 
             
                    }
         | 
| 144 153 |  | 
| @@ -147,7 +156,7 @@ size_t ZSTD_compressBlock_doubleFast_generic( | |
| 147 156 | 
             
                      && ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)))) {
         | 
| 148 157 | 
             
                        mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
         | 
| 149 158 | 
             
                        ip++;
         | 
| 150 | 
            -
                        ZSTD_storeSeq(seqStore, ip-anchor, anchor, 0, mLength-MINMATCH);
         | 
| 159 | 
            +
                        ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, 0, mLength-MINMATCH);
         | 
| 151 160 | 
             
                        goto _match_stored;
         | 
| 152 161 | 
             
                    }
         | 
| 153 162 |  | 
| @@ -170,8 +179,7 @@ size_t ZSTD_compressBlock_doubleFast_generic( | |
| 170 179 | 
             
                            offset = (U32)(current - dictMatchIndexL - dictIndexDelta);
         | 
| 171 180 | 
             
                            while (((ip>anchor) & (dictMatchL>dictStart)) && (ip[-1] == dictMatchL[-1])) { ip--; dictMatchL--; mLength++; } /* catch up */
         | 
| 172 181 | 
             
                            goto _match_found;
         | 
| 173 | 
            -
             | 
| 174 | 
            -
                    }
         | 
| 182 | 
            +
                    }   }
         | 
| 175 183 |  | 
| 176 184 | 
             
                    if (matchIndexS > prefixLowestIndex) {
         | 
| 177 185 | 
             
                        /* check prefix short match */
         | 
| @@ -186,16 +194,14 @@ size_t ZSTD_compressBlock_doubleFast_generic( | |
| 186 194 |  | 
| 187 195 | 
             
                        if (match > dictStart && MEM_read32(match) == MEM_read32(ip)) {
         | 
| 188 196 | 
             
                            goto _search_next_long;
         | 
| 189 | 
            -
             | 
| 190 | 
            -
                    }
         | 
| 197 | 
            +
                    }   }
         | 
| 191 198 |  | 
| 192 199 | 
             
                    ip += ((ip-anchor) >> kSearchStrength) + 1;
         | 
| 193 200 | 
             
                    continue;
         | 
| 194 201 |  | 
| 195 202 | 
             
            _search_next_long:
         | 
| 196 203 |  | 
| 197 | 
            -
                    {
         | 
| 198 | 
            -
                        size_t const hl3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
         | 
| 204 | 
            +
                    {   size_t const hl3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
         | 
| 199 205 | 
             
                        size_t const dictHLNext = ZSTD_hashPtr(ip+1, dictHBitsL, 8);
         | 
| 200 206 | 
             
                        U32 const matchIndexL3 = hashLong[hl3];
         | 
| 201 207 | 
             
                        const BYTE* matchL3 = base + matchIndexL3;
         | 
| @@ -221,9 +227,7 @@ _search_next_long: | |
| 221 227 | 
             
                                offset = (U32)(current + 1 - dictMatchIndexL3 - dictIndexDelta);
         | 
| 222 228 | 
             
                                while (((ip>anchor) & (dictMatchL3>dictStart)) && (ip[-1] == dictMatchL3[-1])) { ip--; dictMatchL3--; mLength++; } /* catch up */
         | 
| 223 229 | 
             
                                goto _match_found;
         | 
| 224 | 
            -
             | 
| 225 | 
            -
                        }
         | 
| 226 | 
            -
                    }
         | 
| 230 | 
            +
                    }   }   }
         | 
| 227 231 |  | 
| 228 232 | 
             
                    /* if no long +1 match, explore the short match we found */
         | 
| 229 233 | 
             
                    if (dictMode == ZSTD_dictMatchState && matchIndexS < prefixLowestIndex) {
         | 
| @@ -242,7 +246,7 @@ _match_found: | |
| 242 246 | 
             
                    offset_2 = offset_1;
         | 
| 243 247 | 
             
                    offset_1 = offset;
         | 
| 244 248 |  | 
| 245 | 
            -
                    ZSTD_storeSeq(seqStore, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
         | 
| 249 | 
            +
                    ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
         | 
| 246 250 |  | 
| 247 251 | 
             
            _match_stored:
         | 
| 248 252 | 
             
                    /* match found */
         | 
| @@ -250,11 +254,14 @@ _match_stored: | |
| 250 254 | 
             
                    anchor = ip;
         | 
| 251 255 |  | 
| 252 256 | 
             
                    if (ip <= ilimit) {
         | 
| 253 | 
            -
                        /*  | 
| 254 | 
            -
                         | 
| 255 | 
            -
             | 
| 256 | 
            -
             | 
| 257 | 
            -
                             | 
| 257 | 
            +
                        /* Complementary insertion */
         | 
| 258 | 
            +
                        /* done after iLimit test, as candidates could be > iend-8 */
         | 
| 259 | 
            +
                        {   U32 const indexToInsert = current+2;
         | 
| 260 | 
            +
                            hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert;
         | 
| 261 | 
            +
                            hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
         | 
| 262 | 
            +
                            hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert;
         | 
| 263 | 
            +
                            hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base);
         | 
| 264 | 
            +
                        }
         | 
| 258 265 |  | 
| 259 266 | 
             
                        /* check immediate repcode */
         | 
| 260 267 | 
             
                        if (dictMode == ZSTD_dictMatchState) {
         | 
| @@ -278,8 +285,7 @@ _match_stored: | |
| 278 285 | 
             
                                    continue;
         | 
| 279 286 | 
             
                                }
         | 
| 280 287 | 
             
                                break;
         | 
| 281 | 
            -
             | 
| 282 | 
            -
                        }
         | 
| 288 | 
            +
                        }   }
         | 
| 283 289 |  | 
| 284 290 | 
             
                        if (dictMode == ZSTD_noDict) {
         | 
| 285 291 | 
             
                            while ( (ip <= ilimit)
         | 
| @@ -294,14 +300,15 @@ _match_stored: | |
| 294 300 | 
             
                                ip += rLength;
         | 
| 295 301 | 
             
                                anchor = ip;
         | 
| 296 302 | 
             
                                continue;   /* faster when present ... (?) */
         | 
| 297 | 
            -
             | 
| 303 | 
            +
                    }   }   }
         | 
| 304 | 
            +
                }   /* while (ip < ilimit) */
         | 
| 298 305 |  | 
| 299 306 | 
             
                /* save reps for next block */
         | 
| 300 307 | 
             
                rep[0] = offset_1 ? offset_1 : offsetSaved;
         | 
| 301 308 | 
             
                rep[1] = offset_2 ? offset_2 : offsetSaved;
         | 
| 302 309 |  | 
| 303 310 | 
             
                /* Return the last literals size */
         | 
| 304 | 
            -
                return iend - anchor;
         | 
| 311 | 
            +
                return (size_t)(iend - anchor);
         | 
| 305 312 | 
             
            }
         | 
| 306 313 |  | 
| 307 314 |  | 
| @@ -360,10 +367,15 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic( | |
| 360 367 | 
             
                const BYTE* anchor = istart;
         | 
| 361 368 | 
             
                const BYTE* const iend = istart + srcSize;
         | 
| 362 369 | 
             
                const BYTE* const ilimit = iend - 8;
         | 
| 363 | 
            -
                const U32   prefixStartIndex = ms->window.dictLimit;
         | 
| 364 370 | 
             
                const BYTE* const base = ms->window.base;
         | 
| 371 | 
            +
                const U32   endIndex = (U32)((size_t)(istart - base) + srcSize);
         | 
| 372 | 
            +
                const U32   maxDistance = 1U << cParams->windowLog;
         | 
| 373 | 
            +
                const U32   lowestValid = ms->window.lowLimit;
         | 
| 374 | 
            +
                const U32   lowLimit = (endIndex - lowestValid > maxDistance) ? endIndex - maxDistance : lowestValid;
         | 
| 375 | 
            +
                const U32   dictStartIndex = lowLimit;
         | 
| 376 | 
            +
                const U32   dictLimit = ms->window.dictLimit;
         | 
| 377 | 
            +
                const U32   prefixStartIndex = (dictLimit > lowLimit) ? dictLimit : lowLimit;
         | 
| 365 378 | 
             
                const BYTE* const prefixStart = base + prefixStartIndex;
         | 
| 366 | 
            -
                const U32   dictStartIndex = ms->window.lowLimit;
         | 
| 367 379 | 
             
                const BYTE* const dictBase = ms->window.dictBase;
         | 
| 368 380 | 
             
                const BYTE* const dictStart = dictBase + dictStartIndex;
         | 
| 369 381 | 
             
                const BYTE* const dictEnd = dictBase + prefixStartIndex;
         | 
| @@ -371,6 +383,10 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic( | |
| 371 383 |  | 
| 372 384 | 
             
                DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_extDict_generic (srcSize=%zu)", srcSize);
         | 
| 373 385 |  | 
| 386 | 
            +
                /* if extDict is invalidated due to maxDistance, switch to "regular" variant */
         | 
| 387 | 
            +
                if (prefixStartIndex == dictStartIndex)
         | 
| 388 | 
            +
                    return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, mls, ZSTD_noDict);
         | 
| 389 | 
            +
             | 
| 374 390 | 
             
                /* Search Loop */
         | 
| 375 391 | 
             
                while (ip < ilimit) {  /* < instead of <=, because (ip+1) */
         | 
| 376 392 | 
             
                    const size_t hSmall = ZSTD_hashPtr(ip, hBitsS, mls);
         | 
| @@ -396,7 +412,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic( | |
| 396 412 | 
             
                        const BYTE* repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
         | 
| 397 413 | 
             
                        mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4;
         | 
| 398 414 | 
             
                        ip++;
         | 
| 399 | 
            -
                        ZSTD_storeSeq(seqStore, ip-anchor, anchor, 0, mLength-MINMATCH);
         | 
| 415 | 
            +
                        ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, 0, mLength-MINMATCH);
         | 
| 400 416 | 
             
                    } else {
         | 
| 401 417 | 
             
                        if ((matchLongIndex > dictStartIndex) && (MEM_read64(matchLong) == MEM_read64(ip))) {
         | 
| 402 418 | 
             
                            const BYTE* const matchEnd = matchLongIndex < prefixStartIndex ? dictEnd : iend;
         | 
| @@ -407,7 +423,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic( | |
| 407 423 | 
             
                            while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; }   /* catch up */
         | 
| 408 424 | 
             
                            offset_2 = offset_1;
         | 
| 409 425 | 
             
                            offset_1 = offset;
         | 
| 410 | 
            -
                            ZSTD_storeSeq(seqStore, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
         | 
| 426 | 
            +
                            ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
         | 
| 411 427 |  | 
| 412 428 | 
             
                        } else if ((matchIndex > dictStartIndex) && (MEM_read32(match) == MEM_read32(ip))) {
         | 
| 413 429 | 
             
                            size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
         | 
| @@ -432,23 +448,27 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic( | |
| 432 448 | 
             
                            }
         | 
| 433 449 | 
             
                            offset_2 = offset_1;
         | 
| 434 450 | 
             
                            offset_1 = offset;
         | 
| 435 | 
            -
                            ZSTD_storeSeq(seqStore, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
         | 
| 451 | 
            +
                            ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
         | 
| 436 452 |  | 
| 437 453 | 
             
                        } else {
         | 
| 438 454 | 
             
                            ip += ((ip-anchor) >> kSearchStrength) + 1;
         | 
| 439 455 | 
             
                            continue;
         | 
| 440 456 | 
             
                    }   }
         | 
| 441 457 |  | 
| 442 | 
            -
                    /*  | 
| 458 | 
            +
                    /* move to next sequence start */
         | 
| 443 459 | 
             
                    ip += mLength;
         | 
| 444 460 | 
             
                    anchor = ip;
         | 
| 445 461 |  | 
| 446 462 | 
             
                    if (ip <= ilimit) {
         | 
| 447 | 
            -
                        /*  | 
| 448 | 
            -
                         | 
| 449 | 
            -
                         | 
| 450 | 
            -
             | 
| 451 | 
            -
             | 
| 463 | 
            +
                        /* Complementary insertion */
         | 
| 464 | 
            +
                        /* done after iLimit test, as candidates could be > iend-8 */
         | 
| 465 | 
            +
                        {   U32 const indexToInsert = current+2;
         | 
| 466 | 
            +
                            hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert;
         | 
| 467 | 
            +
                            hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
         | 
| 468 | 
            +
                            hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert;
         | 
| 469 | 
            +
                            hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base);
         | 
| 470 | 
            +
                        }
         | 
| 471 | 
            +
             | 
| 452 472 | 
             
                        /* check immediate repcode */
         | 
| 453 473 | 
             
                        while (ip <= ilimit) {
         | 
| 454 474 | 
             
                            U32 const current2 = (U32)(ip-base);
         | 
| @@ -475,7 +495,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic( | |
| 475 495 | 
             
                rep[1] = offset_2;
         | 
| 476 496 |  | 
| 477 497 | 
             
                /* Return the last literals size */
         | 
| 478 | 
            -
                return iend - anchor;
         | 
| 498 | 
            +
                return (size_t)(iend - anchor);
         | 
| 479 499 | 
             
            }
         | 
| 480 500 |  | 
| 481 501 |  | 
| @@ -13,7 +13,8 @@ | |
| 13 13 |  | 
| 14 14 |  | 
| 15 15 | 
             
            void ZSTD_fillHashTable(ZSTD_matchState_t* ms,
         | 
| 16 | 
            -
                                    void const | 
| 16 | 
            +
                                    const void* const end,
         | 
| 17 | 
            +
                                    ZSTD_dictTableLoadMethod_e dtlm)
         | 
| 17 18 | 
             
            {
         | 
| 18 19 | 
             
                const ZSTD_compressionParameters* const cParams = &ms->cParams;
         | 
| 19 20 | 
             
                U32* const hashTable = ms->hashTable;
         | 
| @@ -41,6 +42,7 @@ void ZSTD_fillHashTable(ZSTD_matchState_t* ms, | |
| 41 42 | 
             
                }   }   }   }
         | 
| 42 43 | 
             
            }
         | 
| 43 44 |  | 
| 45 | 
            +
             | 
| 44 46 | 
             
            FORCE_INLINE_TEMPLATE
         | 
| 45 47 | 
             
            size_t ZSTD_compressBlock_fast_generic(
         | 
| 46 48 | 
             
                    ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
         | 
| @@ -58,7 +60,10 @@ size_t ZSTD_compressBlock_fast_generic( | |
| 58 60 | 
             
                const BYTE* ip0 = istart;
         | 
| 59 61 | 
             
                const BYTE* ip1;
         | 
| 60 62 | 
             
                const BYTE* anchor = istart;
         | 
| 61 | 
            -
                const U32    | 
| 63 | 
            +
                const U32   endIndex = (U32)((size_t)(istart - base) + srcSize);
         | 
| 64 | 
            +
                const U32   maxDistance = 1U << cParams->windowLog;
         | 
| 65 | 
            +
                const U32   validStartIndex = ms->window.dictLimit;
         | 
| 66 | 
            +
                const U32   prefixStartIndex = (endIndex - validStartIndex > maxDistance) ? endIndex - maxDistance : validStartIndex;
         | 
| 62 67 | 
             
                const BYTE* const prefixStart = base + prefixStartIndex;
         | 
| 63 68 | 
             
                const BYTE* const iend = istart + srcSize;
         | 
| 64 69 | 
             
                const BYTE* const ilimit = iend - HASH_READ_SIZE;
         | 
| @@ -165,7 +170,7 @@ _match: /* Requires: ip0, match0, offcode */ | |
| 165 170 | 
             
                rep[1] = offset_2 ? offset_2 : offsetSaved;
         | 
| 166 171 |  | 
| 167 172 | 
             
                /* Return the last literals size */
         | 
| 168 | 
            -
                return iend - anchor;
         | 
| 173 | 
            +
                return (size_t)(iend - anchor);
         | 
| 169 174 | 
             
            }
         | 
| 170 175 |  | 
| 171 176 |  | 
| @@ -222,8 +227,15 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic( | |
| 222 227 | 
             
                const U32 dictAndPrefixLength  = (U32)(ip - prefixStart + dictEnd - dictStart);
         | 
| 223 228 | 
             
                const U32 dictHLog             = dictCParams->hashLog;
         | 
| 224 229 |  | 
| 225 | 
            -
                /*  | 
| 226 | 
            -
                 *  | 
| 230 | 
            +
                /* if a dictionary is still attached, it necessarily means that
         | 
| 231 | 
            +
                 * it is within window size. So we just check it. */
         | 
| 232 | 
            +
                const U32 maxDistance = 1U << cParams->windowLog;
         | 
| 233 | 
            +
                const U32 endIndex = (U32)((size_t)(ip - base) + srcSize);
         | 
| 234 | 
            +
                assert(endIndex - prefixStartIndex <= maxDistance);
         | 
| 235 | 
            +
                (void)maxDistance; (void)endIndex;   /* these variables are not used when assert() is disabled */
         | 
| 236 | 
            +
             | 
| 237 | 
            +
                /* ensure there will be no no underflow
         | 
| 238 | 
            +
                 * when translating a dict index into a local index */
         | 
| 227 239 | 
             
                assert(prefixStartIndex >= (U32)(dictEnd - dictBase));
         | 
| 228 240 |  | 
| 229 241 | 
             
                /* init */
         | 
| @@ -251,7 +263,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic( | |
| 251 263 | 
             
                        const BYTE* const repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
         | 
| 252 264 | 
             
                        mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4;
         | 
| 253 265 | 
             
                        ip++;
         | 
| 254 | 
            -
                        ZSTD_storeSeq(seqStore, ip-anchor, anchor, 0, mLength-MINMATCH);
         | 
| 266 | 
            +
                        ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, 0, mLength-MINMATCH);
         | 
| 255 267 | 
             
                    } else if ( (matchIndex <= prefixStartIndex) ) {
         | 
| 256 268 | 
             
                        size_t const dictHash = ZSTD_hashPtr(ip, dictHLog, mls);
         | 
| 257 269 | 
             
                        U32 const dictMatchIndex = dictHashTable[dictHash];
         | 
| @@ -271,7 +283,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic( | |
| 271 283 | 
             
                            } /* catch up */
         | 
| 272 284 | 
             
                            offset_2 = offset_1;
         | 
| 273 285 | 
             
                            offset_1 = offset;
         | 
| 274 | 
            -
                            ZSTD_storeSeq(seqStore, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
         | 
| 286 | 
            +
                            ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
         | 
| 275 287 | 
             
                        }
         | 
| 276 288 | 
             
                    } else if (MEM_read32(match) != MEM_read32(ip)) {
         | 
| 277 289 | 
             
                        /* it's not a match, and we're not going to check the dictionary */
         | 
| @@ -286,7 +298,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic( | |
| 286 298 | 
             
                             && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
         | 
| 287 299 | 
             
                        offset_2 = offset_1;
         | 
| 288 300 | 
             
                        offset_1 = offset;
         | 
| 289 | 
            -
                        ZSTD_storeSeq(seqStore, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
         | 
| 301 | 
            +
                        ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
         | 
| 290 302 | 
             
                    }
         | 
| 291 303 |  | 
| 292 304 | 
             
                    /* match found */
         | 
| @@ -327,7 +339,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic( | |
| 327 339 | 
             
                rep[1] = offset_2 ? offset_2 : offsetSaved;
         | 
| 328 340 |  | 
| 329 341 | 
             
                /* Return the last literals size */
         | 
| 330 | 
            -
                return iend - anchor;
         | 
| 342 | 
            +
                return (size_t)(iend - anchor);
         | 
| 331 343 | 
             
            }
         | 
| 332 344 |  | 
| 333 345 | 
             
            size_t ZSTD_compressBlock_fast_dictMatchState(
         | 
| @@ -366,15 +378,24 @@ static size_t ZSTD_compressBlock_fast_extDict_generic( | |
| 366 378 | 
             
                const BYTE* const istart = (const BYTE*)src;
         | 
| 367 379 | 
             
                const BYTE* ip = istart;
         | 
| 368 380 | 
             
                const BYTE* anchor = istart;
         | 
| 369 | 
            -
                const U32    | 
| 381 | 
            +
                const U32   endIndex = (U32)((size_t)(istart - base) + srcSize);
         | 
| 382 | 
            +
                const U32   maxDistance = 1U << cParams->windowLog;
         | 
| 383 | 
            +
                const U32   validLow = ms->window.lowLimit;
         | 
| 384 | 
            +
                const U32   lowLimit = (endIndex - validLow > maxDistance) ? endIndex - maxDistance : validLow;
         | 
| 385 | 
            +
                const U32   dictStartIndex = lowLimit;
         | 
| 370 386 | 
             
                const BYTE* const dictStart = dictBase + dictStartIndex;
         | 
| 371 | 
            -
                const U32    | 
| 387 | 
            +
                const U32   dictLimit = ms->window.dictLimit;
         | 
| 388 | 
            +
                const U32   prefixStartIndex = dictLimit < lowLimit ? lowLimit : dictLimit;
         | 
| 372 389 | 
             
                const BYTE* const prefixStart = base + prefixStartIndex;
         | 
| 373 390 | 
             
                const BYTE* const dictEnd = dictBase + prefixStartIndex;
         | 
| 374 391 | 
             
                const BYTE* const iend = istart + srcSize;
         | 
| 375 392 | 
             
                const BYTE* const ilimit = iend - 8;
         | 
| 376 393 | 
             
                U32 offset_1=rep[0], offset_2=rep[1];
         | 
| 377 394 |  | 
| 395 | 
            +
                /* switch to "regular" variant if extDict is invalidated due to maxDistance */
         | 
| 396 | 
            +
                if (prefixStartIndex == dictStartIndex)
         | 
| 397 | 
            +
                    return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, mls);
         | 
| 398 | 
            +
             | 
| 378 399 | 
             
                /* Search Loop */
         | 
| 379 400 | 
             
                while (ip < ilimit) {  /* < instead of <=, because (ip+1) */
         | 
| 380 401 | 
             
                    const size_t h = ZSTD_hashPtr(ip, hlog, mls);
         | 
| @@ -394,7 +415,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic( | |
| 394 415 | 
             
                        const BYTE* repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
         | 
| 395 416 | 
             
                        mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4;
         | 
| 396 417 | 
             
                        ip++;
         | 
| 397 | 
            -
                        ZSTD_storeSeq(seqStore, ip-anchor, anchor, 0, mLength-MINMATCH);
         | 
| 418 | 
            +
                        ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, 0, mLength-MINMATCH);
         | 
| 398 419 | 
             
                    } else {
         | 
| 399 420 | 
             
                        if ( (matchIndex < dictStartIndex) ||
         | 
| 400 421 | 
             
                             (MEM_read32(match) != MEM_read32(ip)) ) {
         | 
| @@ -410,7 +431,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic( | |
| 410 431 | 
             
                            offset = current - matchIndex;
         | 
| 411 432 | 
             
                            offset_2 = offset_1;
         | 
| 412 433 | 
             
                            offset_1 = offset;
         | 
| 413 | 
            -
                            ZSTD_storeSeq(seqStore, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
         | 
| 434 | 
            +
                            ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
         | 
| 414 435 | 
             
                    }   }
         | 
| 415 436 |  | 
| 416 437 | 
             
                    /* found a match : store it */
         | 
| @@ -445,7 +466,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic( | |
| 445 466 | 
             
                rep[1] = offset_2;
         | 
| 446 467 |  | 
| 447 468 | 
             
                /* Return the last literals size */
         | 
| 448 | 
            -
                return iend - anchor;
         | 
| 469 | 
            +
                return (size_t)(iend - anchor);
         | 
| 449 470 | 
             
            }
         | 
| 450 471 |  | 
| 451 472 |  |