diff --git a/ggml/src/gguf.cpp b/ggml/src/gguf.cpp index 7d6cd6110a..31d32ce336 100644 --- a/ggml/src/gguf.cpp +++ b/ggml/src/gguf.cpp @@ -15,6 +15,8 @@ #include #include +#define GGUF_MAX_STRING_LENGTH (1024*1024*1024) + template struct type_to_gguf_type; @@ -277,10 +279,40 @@ struct gguf_reader { if (!read(size)) { return false; } - dst.resize(size); + if (size > GGUF_MAX_STRING_LENGTH) { + GGML_LOG_ERROR("%s: string length %" PRIu64 " exceeds maximum %d\n", __func__, size, GGUF_MAX_STRING_LENGTH); + return false; + } + const uint64_t n_remain = remain(); + if (size > n_remain) { + GGML_LOG_ERROR("%s: string length %" PRIu64 " exceeds remaining file size %" PRIu64 "\n", __func__, size, n_remain); + return false; + } + dst.resize(static_cast(size)); return fread(dst.data(), 1, dst.length(), file) == dst.length(); } + // remaining bytes in the file + uint64_t remain() const { + long cur = ftell(file); + if (cur < 0) { + return 0; + } + if (fseek(file, 0, SEEK_END) != 0) { + fseek(file, cur, SEEK_SET); + + return 0; + } + const long end = ftell(file); + if (end < 0) { + fseek(file, cur, SEEK_SET); + + return 0; + } + fseek(file, cur, SEEK_SET); + return static_cast(end - cur); + } + bool read(void * dst, const size_t size) const { return fread(dst, 1, size, file) == size; }