Skip to content

Commit 7675c55

Browse files
gguf: fix failure on version == 0 (ggml-org#13956)
1 parent 5e1c3ae commit 7675c55

File tree

2 files changed

+16
-7
lines changed

2 files changed

+16
-7
lines changed

ggml/src/gguf.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -347,25 +347,28 @@ struct gguf_context * gguf_init_from_file_impl(FILE * file, struct gguf_init_par
347347
int64_t n_tensors = 0;
348348

349349
if (ok && gr.read(ctx->version)) {
350+
if (ok && ctx->version == 0) {
351+
GGML_LOG_ERROR("%s: bad GGUF version: %" PRIu32 "\n", __func__, ctx->version);
352+
ok = false;
353+
}
354+
350355
/*
351356
* bit layout is different when reading non-native endian models.
352357
* assuming that the GGUF version is 3, the non-native endian model
353358
* would read it as 0x30000000. we can use the AND operation against
354359
* the last 4 hexadecimal digits to check if the model is the same
355360
* endianness as the host system.
356361
*/
357-
if ((ctx->version & 0x0000FFFF) == 0x00000000) {
362+
if (ok && (ctx->version & 0x0000FFFF) == 0x00000000) {
358363
GGML_LOG_ERROR("%s: failed to load model: this GGUF file version %" PRIu32 " is extremely large, is there a mismatch between the host and model endianness?\n", __func__, ctx->version);
359-
gguf_free(ctx);
360-
return nullptr;
364+
ok = false;
361365
}
362366

363-
GGML_ASSERT(ctx->version > 0 && ctx->version <= 65535);
364-
if (ctx->version == 1) {
367+
if (ok && ctx->version == 1) {
365368
GGML_LOG_ERROR("%s: GGUFv1 is no longer supported, please use a more up-to-date version\n", __func__);
366369
ok = false;
367370
}
368-
if (ctx->version > GGUF_VERSION) {
371+
if (ok && ctx->version > GGUF_VERSION) {
369372
GGML_LOG_ERROR("%s: this GGUF file is version %" PRIu32 " but this software only supports up to version %d\n",
370373
__func__, ctx->version, GGUF_VERSION);
371374
ok = false;

tests/test-gguf.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ constexpr int offset_has_data = 3000;
1616

1717
enum handcrafted_file_type {
1818
HANDCRAFTED_HEADER_BAD_MAGIC = 10,
19+
HANDCRAFTED_HEADER_BAD_VERSION_0 = 15,
1920
HANDCRAFTED_HEADER_BAD_VERSION_1 = 20,
2021
HANDCRAFTED_HEADER_BAD_VERSION_FUTURE = 30,
2122
HANDCRAFTED_HEADER_BAD_N_TENSORS = 40,
@@ -51,6 +52,7 @@ enum handcrafted_file_type {
5152
static std::string handcrafted_file_type_name(const enum handcrafted_file_type hft) {
5253
switch (hft) {
5354
case HANDCRAFTED_HEADER_BAD_MAGIC: return "HEADER_BAD_MAGIC";
55+
case HANDCRAFTED_HEADER_BAD_VERSION_0: return "HEADER_BAD_VERSION_0";
5456
case HANDCRAFTED_HEADER_BAD_VERSION_1: return "HEADER_BAD_VERSION_1";
5557
case HANDCRAFTED_HEADER_BAD_VERSION_FUTURE: return "HEADER_BAD_VERSION_FUTURE";
5658
case HANDCRAFTED_HEADER_BAD_N_KV: return "HEADER_BAD_N_KV";
@@ -171,7 +173,10 @@ static FILE * get_handcrafted_file(const unsigned int seed, const enum handcraft
171173
helper_write(file, GGUF_MAGIC, 4);
172174
}
173175

174-
if (hft == HANDCRAFTED_HEADER_BAD_VERSION_1) {
176+
if (hft == HANDCRAFTED_HEADER_BAD_VERSION_0) {
177+
const uint32_t version = 0;
178+
helper_write(file, version);
179+
} else if (hft == HANDCRAFTED_HEADER_BAD_VERSION_1) {
175180
const uint32_t version = 1;
176181
helper_write(file, version);
177182
} else if (hft == HANDCRAFTED_HEADER_BAD_VERSION_FUTURE) {
@@ -660,6 +665,7 @@ static std::pair<int, int> test_handcrafted_file(const unsigned int seed) {
660665

661666
const std::vector<handcrafted_file_type> hfts = {
662667
HANDCRAFTED_HEADER_BAD_MAGIC,
668+
HANDCRAFTED_HEADER_BAD_VERSION_0,
663669
HANDCRAFTED_HEADER_BAD_VERSION_1,
664670
HANDCRAFTED_HEADER_BAD_VERSION_FUTURE,
665671
HANDCRAFTED_HEADER_BAD_N_KV,

0 commit comments

Comments
 (0)