`ZSTD_getDictID_fromFrame` returns a skippable frame's magic variant as its dictionary ID

Aperta Adatta ai principianti
#4,881 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
1/5
Tempo stimato
Meno di un'ora
Idoneità per principianti
78/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
c
Ambito
data

Direzione di ricerca

Inizia da ZSTD_getDictID_fromFrame in lib/decompress/zstd_decompress.c, vicino alla riga 1643, e confrontala con il valore di ritorno documentato in lib/zstd.h intorno alle righe 1061-1071. Compila il reproducer dell'issue contro lib/libzstd.a per confermare che stampa 5 per il frame skippable. Il lavoro è completo quando la funzione restituisce 0 per i frame skippable, ZSTD_getFrameHeader continua a segnalare la variante in dictID e la suite di test esistente passa.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Describe the bug
Since v1.5.7, ZSTD_getDictID_fromFrame returns the magic variant (0-15) of a skippable frame as if it were a dictionary ID. zstd.h (L1061-L1071) documents a return of 0 when "This is not a Zstandard frame", and a skippable frame needs no dictionary.

Cause: commit a2ff6ea78 made ZSTD_getFrameHeader report the magic variant in dictID for skippable frames, which is documented on ZSTD_FrameHeader. ZSTD_getDictID_fromFrame (L1643-L1649) returns that field without checking the frame type.

To Reproduce
A skippable frame with magic 0x184D2A55 (variant 5) and 3 bytes of user data: 55 2a 4d 18 03 00 00 00 61 62 63.

  1. make -C lib libzstd.a
  2. cc -Ilib poc.c lib/libzstd.a -o poc && ./poc
  3. Output: ZSTD_getDictID_fromFrame(skippable frame, variant 5) = 5
poc.c
#include <stdio.h>
#include "zstd.h"

static const unsigned char frame[] = { 0x55, 0x2A, 0x4D, 0x18, 3, 0, 0, 0, 'a', 'b', 'c' };

int main(void)
{
	unsigned id = ZSTD_getDictID_fromFrame(frame, sizeof frame);
	printf("ZSTD_getDictID_fromFrame(skippable frame, variant 5) = %u\n", id);
	return 0;
}

Expected behavior
ZSTD_getDictID_fromFrame returns 0 for a skippable frame, as v1.5.6 and earlier do.

Desktop:

  • OS: Ubuntu 24.04.4 LTS
  • Version: dev 49cf51799 and v1.5.7 return 5
  • Compiler: gcc 13.3.0
  • Flags: default lib/Makefile flags, PoC built with -O2
  • Other relevant hardware specs: x86_64
  • Build system: Makefile

Additional context
Suggested fix: return 0 for skippable frames in ZSTD_getDictID_fromFrame and keep the variant in ZSTD_getFrameHeader, as documented. With it the PoC prints 0, and tests pass.

--- a/lib/decompress/zstd_decompress.c
+++ b/lib/decompress/zstd_decompress.c
@@ -1645,6 +1645,7 @@ unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize)
     ZSTD_FrameHeader zfp = { 0, 0, 0, ZSTD_frame, 0, 0, 0, 0, 0 };
     size_t const hError = ZSTD_getFrameHeader(&zfp, src, srcSize);
     if (ZSTD_isError(hError)) return 0;
+    if (zfp.frameType == ZSTD_skippableFrame) return 0;
     return zfp.dictID;
 }
 

Found by genproof.com Formal Verification Agent. Reviewed and approved by a human.

Lingua principale
C
Stelle
28.1k
Fork
2.7k
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di facebook/zstd

Tutte le issue di facebook/zstd

Issue simili

Altre issue su C

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.