@@ -139,7 +139,11 @@ static U32 FUZ_highbit32(U32 v32)
139139 } \
140140}
141141#define CHECK_EQ (lhs , rhs ) CHECK_OP(==, lhs, rhs)
142+ #define CHECK_NE (lhs , rhs ) CHECK_OP(!=, lhs, rhs)
142143#define CHECK_LT (lhs , rhs ) CHECK_OP(<, lhs, rhs)
144+ #define CHECK_GT (lhs , rhs ) CHECK_OP(>, lhs, rhs)
145+ #define CHECK_LE (lhs , rhs ) CHECK_OP(<=, lhs, rhs)
146+ #define CHECK_GE (lhs , rhs ) CHECK_OP(>=, lhs, rhs)
143147
144148
145149/*=============================================
@@ -3377,6 +3381,128 @@ static int basicUnitTests(U32 const seed, double compressibility)
33773381 }
33783382 DISPLAYLEVEL (3 , "OK \n" );
33793383
3384+ DISPLAYLEVEL (3 , "test%3i : check window size when applying protocol constraints : \n" , testNb ++ );
3385+ {
3386+ const size_t dictSizes [] = { 0 , 128 , 128 KB , 4 MB , 13421772 , 13421773 , 107374182 , 107374183 , 150 MB };
3387+ const size_t nbDictSizes = sizeof (dictSizes ) / sizeof (dictSizes [0 ]);
3388+ size_t dictSizeIdx ;
3389+ const size_t bigDictSize = dictSizes [nbDictSizes - 1 ];
3390+ char * bigDictBuffer = malloc (bigDictSize );
3391+ const ZSTD_ConstrainWindow_e constraints [] = {
3392+ ZSTD_ConstrainWindow_disable ,
3393+ ZSTD_ConstrainWindow_HTTP_Zstd ,
3394+ ZSTD_ConstrainWindow_HTTP_DCZ
3395+ };
3396+ const char * constraintNames [] = {
3397+ "ZSTD_ConstrainWindow_disable" ,
3398+ "ZSTD_ConstrainWindow_HTTP_Zstd" ,
3399+ "ZSTD_ConstrainWindow_HTTP_DCZ"
3400+ };
3401+ const size_t nbConstraints = sizeof (constraints ) / sizeof (constraints [0 ]);
3402+ size_t constraintIdx ;
3403+ const unsigned long long inputSizes [] = { 0 , 1ull << 10 , 1ull << 23 , 1ull << 27 , 1ull << 31 , 1ull << 63 , ZSTD_CONTENTSIZE_UNKNOWN };
3404+ const size_t nbInputSizes = sizeof (inputSizes ) / sizeof (inputSizes [0 ]);
3405+ size_t inputSizeIdx ;
3406+ const int windowLogs [] = { 0 , 15 , 25 , ZSTD_WINDOWLOG_MAX };
3407+ const size_t nbWindowLogs = sizeof (windowLogs ) / sizeof (windowLogs [0 ]);
3408+ size_t windowLogIdx ;
3409+
3410+ CHECK_NE (bigDictBuffer , NULL );
3411+ memset (bigDictBuffer , 0 , bigDictSize );
3412+
3413+ for (constraintIdx = 0 ; constraintIdx < nbConstraints ; constraintIdx ++ ) {
3414+ const ZSTD_ConstrainWindow_e constraint = constraints [constraintIdx ];
3415+ for (inputSizeIdx = 0 ; inputSizeIdx < nbInputSizes ; inputSizeIdx ++ ) {
3416+ const unsigned long long inputSize = inputSizes [inputSizeIdx ];
3417+ for (dictSizeIdx = 0 ; dictSizeIdx < nbDictSizes ; dictSizeIdx ++ ) {
3418+ dictSize = dictSizes [dictSizeIdx ];
3419+ if (constraint != ZSTD_ConstrainWindow_HTTP_DCZ && (dictSize != 0 && dictSize != dictSizes [nbDictSizes - 1 ])) {
3420+ continue ;
3421+ }
3422+ for (windowLogIdx = 0 ; windowLogIdx < nbWindowLogs ; windowLogIdx ++ ) {
3423+ const int windowLog = windowLogs [windowLogIdx ];
3424+ ZSTD_inBuffer input = {CNBuffer , CNBuffSize , 0 };
3425+ ZSTD_outBuffer compressed = {compressedBuffer , compressedBufferSize , 0 };
3426+ ZSTD_FrameHeader zfh ;
3427+ unsigned long long maxWindowSize ;
3428+
3429+ DISPLAYLEVEL (5 ,
3430+ "Checking constraint = %-30s "
3431+ "with input size = %20llu and dict size = %9zu "
3432+ "and windowLog = %2d: " ,
3433+ constraintNames [constraintIdx ],
3434+ inputSize , dictSize , windowLog );
3435+
3436+ if (input .size > 200 KB ) {
3437+ input .size = 200 KB ;
3438+ }
3439+ if (input .size > inputSize ) {
3440+ input .size = inputSize ;
3441+ }
3442+
3443+ ZSTD_CCtx_reset (cctx , ZSTD_reset_session_and_parameters );
3444+ CHECK_Z (ZSTD_CCtx_setParameter (cctx , ZSTD_c_constrainWindowForProtocol , constraint ));
3445+ CHECK_Z (ZSTD_CCtx_setParameter (cctx , ZSTD_c_compressionLevel , 1 ));
3446+ CHECK_Z (ZSTD_CCtx_setParameter (cctx , ZSTD_c_windowLog , windowLog ));
3447+ CHECK_Z (ZSTD_CCtx_setPledgedSrcSize (cctx , inputSize ));
3448+ if (dictSize != 0 ) {
3449+ CHECK_Z (ZSTD_CCtx_loadDictionary_advanced (cctx , bigDictBuffer , dictSize , ZSTD_dlm_byRef , ZSTD_dct_rawContent ));
3450+ }
3451+ CHECK_Z (ZSTD_compressStream2 (cctx , & compressed , & input , inputSize == 0 ? ZSTD_e_end : ZSTD_e_flush ));
3452+
3453+ CHECK_GT (compressed .size , 0 );
3454+
3455+ CHECK_Z (ZSTD_getFrameHeader (& zfh , compressed .dst , compressed .pos ));
3456+
3457+ DISPLAYLEVEL (5 ,
3458+ "got window size = %10llu, Frame size = %20llu, " ,
3459+ zfh .windowSize , zfh .frameContentSize );
3460+
3461+ CHECK_EQ (zfh .frameContentSize , inputSize );
3462+
3463+ switch (constraint ) {
3464+ case ZSTD_ConstrainWindow_auto :
3465+ case ZSTD_ConstrainWindow_disable :
3466+ maxWindowSize = 1ull << ZSTD_WINDOWLOG_MAX ;
3467+ break ;
3468+ case ZSTD_ConstrainWindow_HTTP_Zstd :
3469+ maxWindowSize = 8 MB ;
3470+ break ;
3471+ case ZSTD_ConstrainWindow_HTTP_DCZ :
3472+ maxWindowSize = dictSize * 1.25 ;
3473+ maxWindowSize = maxWindowSize < 8 MB ? 8 MB : maxWindowSize > 128 MB ? 128 MB : maxWindowSize ;
3474+ maxWindowSize = 1 << ZSTD_highbit32 (maxWindowSize );
3475+ break ;
3476+ default :
3477+ CHECK (0 );
3478+ }
3479+
3480+ if (windowLog != 0 && maxWindowSize > (1ull << windowLog )) {
3481+ maxWindowSize = 1ull << windowLog ;
3482+ }
3483+
3484+ if (maxWindowSize > inputSize ) {
3485+ maxWindowSize = inputSize ;
3486+ }
3487+
3488+ DISPLAYLEVEL (5 ,
3489+ "expected window size = %20llu\n" ,
3490+ maxWindowSize );
3491+
3492+ if (windowLog != 0 ) {
3493+ CHECK_EQ (zfh .windowSize , maxWindowSize );
3494+ } else {
3495+ CHECK_LE (zfh .windowSize , maxWindowSize );
3496+ }
3497+ }
3498+ }
3499+ }
3500+ }
3501+
3502+ free (bigDictBuffer );
3503+ }
3504+ DISPLAYLEVEL (3 , "OK \n" );
3505+
33803506 ZSTD_freeCCtx (cctx );
33813507 free (dictBuffer );
33823508 free (samplesSizes );
0 commit comments