@@ -589,49 +589,52 @@ static size_t readSkippableFrameSize(void const* src, size_t srcSize)
589589 sizeU32 = MEM_readLE32 ((BYTE const * )src + ZSTD_FRAMEIDSIZE );
590590 RETURN_ERROR_IF ((U32 )(sizeU32 + ZSTD_SKIPPABLEHEADERSIZE ) < sizeU32 ,
591591 frameParameter_unsupported , "" );
592- {
593- size_t const skippableSize = skippableHeaderSize + sizeU32 ;
592+ { size_t const skippableSize = skippableHeaderSize + sizeU32 ;
594593 RETURN_ERROR_IF (skippableSize > srcSize , srcSize_wrong , "" );
595594 return skippableSize ;
596595 }
597596}
598597
599598/*! ZSTD_readSkippableFrame() :
600- * Retrieves a zstd skippable frame containing data given by src , and writes it to dst buffer.
599+ * Retrieves content of a skippable frame, and writes it to dst buffer.
601600 *
602601 * The parameter magicVariant will receive the magicVariant that was supplied when the frame was written,
603602 * i.e. magicNumber - ZSTD_MAGIC_SKIPPABLE_START. This can be NULL if the caller is not interested
604603 * in the magicVariant.
605604 *
606- * Returns an error if destination buffer is not large enough, or if the frame is not skippable.
605+ * Returns an error if destination buffer is not large enough, or if this is not a valid skippable frame .
607606 *
608607 * @return : number of bytes written or a ZSTD error.
609608 */
610- ZSTDLIB_API size_t ZSTD_readSkippableFrame (void * dst , size_t dstCapacity , unsigned * magicVariant ,
611- const void * src , size_t srcSize )
609+ size_t ZSTD_readSkippableFrame (void * dst , size_t dstCapacity ,
610+ unsigned * magicVariant , /* optional, can be NULL */
611+ const void * src , size_t srcSize )
612612{
613- U32 const magicNumber = MEM_readLE32 (src );
614- size_t skippableFrameSize = readSkippableFrameSize (src , srcSize );
615- size_t skippableContentSize = skippableFrameSize - ZSTD_SKIPPABLEHEADERSIZE ;
616-
617- /* check input validity */
618- RETURN_ERROR_IF (!ZSTD_isSkippableFrame (src , srcSize ), frameParameter_unsupported , "" );
619- RETURN_ERROR_IF (skippableFrameSize < ZSTD_SKIPPABLEHEADERSIZE || skippableFrameSize > srcSize , srcSize_wrong , "" );
620- RETURN_ERROR_IF (skippableContentSize > dstCapacity , dstSize_tooSmall , "" );
613+ RETURN_ERROR_IF (srcSize < ZSTD_SKIPPABLEHEADERSIZE , srcSize_wrong , "" );
621614
622- /* deliver payload */
623- if (skippableContentSize > 0 && dst != NULL )
624- ZSTD_memcpy (dst , (const BYTE * )src + ZSTD_SKIPPABLEHEADERSIZE , skippableContentSize );
625- if (magicVariant != NULL )
626- * magicVariant = magicNumber - ZSTD_MAGIC_SKIPPABLE_START ;
627- return skippableContentSize ;
615+ { U32 const magicNumber = MEM_readLE32 (src );
616+ size_t skippableFrameSize = readSkippableFrameSize (src , srcSize );
617+ size_t skippableContentSize = skippableFrameSize - ZSTD_SKIPPABLEHEADERSIZE ;
618+
619+ /* check input validity */
620+ RETURN_ERROR_IF (!ZSTD_isSkippableFrame (src , srcSize ), frameParameter_unsupported , "" );
621+ RETURN_ERROR_IF (skippableFrameSize < ZSTD_SKIPPABLEHEADERSIZE || skippableFrameSize > srcSize , srcSize_wrong , "" );
622+ RETURN_ERROR_IF (skippableContentSize > dstCapacity , dstSize_tooSmall , "" );
623+
624+ /* deliver payload */
625+ if (skippableContentSize > 0 && dst != NULL )
626+ ZSTD_memcpy (dst , (const BYTE * )src + ZSTD_SKIPPABLEHEADERSIZE , skippableContentSize );
627+ if (magicVariant != NULL )
628+ * magicVariant = magicNumber - ZSTD_MAGIC_SKIPPABLE_START ;
629+ return skippableContentSize ;
630+ }
628631}
629632
630633/** ZSTD_findDecompressedSize() :
631- * compatible with legacy mode
632634 * `srcSize` must be the exact length of some number of ZSTD compressed and/or
633635 * skippable frames
634- * @return : decompressed size of the frames contained */
636+ * note: compatible with legacy mode
637+ * @return : decompressed size of the frames contained */
635638unsigned long long ZSTD_findDecompressedSize (const void * src , size_t srcSize )
636639{
637640 unsigned long long totalDstSize = 0 ;
@@ -641,27 +644,25 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
641644
642645 if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK ) == ZSTD_MAGIC_SKIPPABLE_START ) {
643646 size_t const skippableSize = readSkippableFrameSize (src , srcSize );
644- if (ZSTD_isError (skippableSize )) {
645- return ZSTD_CONTENTSIZE_ERROR ;
646- }
647+ if (ZSTD_isError (skippableSize )) return ZSTD_CONTENTSIZE_ERROR ;
647648 assert (skippableSize <= srcSize );
648649
649650 src = (const BYTE * )src + skippableSize ;
650651 srcSize -= skippableSize ;
651652 continue ;
652653 }
653654
654- { unsigned long long const ret = ZSTD_getFrameContentSize (src , srcSize );
655- if (ret >= ZSTD_CONTENTSIZE_ERROR ) return ret ;
655+ { unsigned long long const fcs = ZSTD_getFrameContentSize (src , srcSize );
656+ if (fcs >= ZSTD_CONTENTSIZE_ERROR ) return fcs ;
656657
657- /* check for overflow */
658- if ( totalDstSize + ret < totalDstSize ) return ZSTD_CONTENTSIZE_ERROR ;
659- totalDstSize += ret ;
658+ if ( totalDstSize + fcs < totalDstSize )
659+ return ZSTD_CONTENTSIZE_ERROR ; /* check for overflow */
660+ totalDstSize += fcs ;
660661 }
662+ /* skip to next frame */
661663 { size_t const frameSrcSize = ZSTD_findFrameCompressedSize (src , srcSize );
662- if (ZSTD_isError (frameSrcSize )) {
663- return ZSTD_CONTENTSIZE_ERROR ;
664- }
664+ if (ZSTD_isError (frameSrcSize )) return ZSTD_CONTENTSIZE_ERROR ;
665+ assert (frameSrcSize <= srcSize );
665666
666667 src = (const BYTE * )src + frameSrcSize ;
667668 srcSize -= frameSrcSize ;
@@ -1091,17 +1092,18 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
10911092 }
10921093#endif
10931094
1094- { U32 const magicNumber = MEM_readLE32 ( src );
1095- DEBUGLOG ( 4 , "reading magic number %08X (expecting %08X)" ,
1096- (unsigned )magicNumber , ZSTD_MAGICNUMBER );
1095+ if ( srcSize >= 4 ) {
1096+ U32 const magicNumber = MEM_readLE32 ( src );
1097+ DEBUGLOG ( 5 , "reading magic number %08X" , (unsigned )magicNumber );
10971098 if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK ) == ZSTD_MAGIC_SKIPPABLE_START ) {
1099+ /* skippable frame detected : skip it */
10981100 size_t const skippableSize = readSkippableFrameSize (src , srcSize );
1099- FORWARD_IF_ERROR (skippableSize , "readSkippableFrameSize failed " );
1101+ FORWARD_IF_ERROR (skippableSize , "invalid skippable frame " );
11001102 assert (skippableSize <= srcSize );
11011103
11021104 src = (const BYTE * )src + skippableSize ;
11031105 srcSize -= skippableSize ;
1104- continue ;
1106+ continue ; /* check next frame */
11051107 } }
11061108
11071109 if (ddict ) {
0 commit comments