gguf : add string length accessor

Add gguf_get_arr_str_len() to obtain the length of a string stored in a
GGUF string array without scanning for the terminator. This allows
callers to pre-compute the exact size of a result buffer before
formatting string arrays (ref:
https://github.com/ggml-org/llama.cpp/pull/30679#discussion_r4324797291).

Also bounds-check the index in gguf_get_arr_str().

Assisted-by: pi:llama.cpp/ggml-org/Qwen3.8-Flash-Next-GGUF (RTX 5090 32GB, DDR5 128GB)
This commit is contained in:
Georgi Gerganov committed 2026-10-20 15:33:27 +03:00
1 parent d8d92973c8
commit e96bb55fdd
3 files changed
+20

No files matched your search

+4
View File
@@ -125,6 +125,10 @@ extern "C" {
// get ith C string from array with given key_id
GGML_API const char * gguf_get_arr_str (const struct gguf_context * ctx, int64_t key_id, size_t i);
// get length of the ith C string from array with given key_id, excluding the terminating NUL
// for a non-array string KV pair, use i = 0
GGML_API size_t gguf_get_arr_str_len(const struct gguf_context * ctx, int64_t key_id, size_t i);
GGML_API int64_t gguf_get_n_tensors (const struct gguf_context * ctx);
GGML_API int64_t gguf_find_tensor (const struct gguf_context * ctx, const char * name); // returns -1 if the tensor is not found
GGML_API size_t gguf_get_tensor_offset(const struct gguf_context * ctx, int64_t tensor_id);
+8
View File
@@ -1096,9 +1096,17 @@ const void * gguf_get_arr_data(const struct gguf_context * ctx, int64_t key_id)
const char * gguf_get_arr_str(const struct gguf_context * ctx, int64_t key_id, size_t i) {
GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx));
GGML_ASSERT(ctx->kv[key_id].get_type() == GGUF_TYPE_STRING);
GGML_ASSERT(i < ctx->kv[key_id].data_string.size());
return ctx->kv[key_id].data_string[i].c_str();
}
size_t gguf_get_arr_str_len(const struct gguf_context * ctx, int64_t key_id, size_t i) {
GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx));
GGML_ASSERT(ctx->kv[key_id].get_type() == GGUF_TYPE_STRING);
GGML_ASSERT(i < ctx->kv[key_id].data_string.size());
return ctx->kv[key_id].data_string[i].size();
}
size_t gguf_get_arr_n(const struct gguf_context * ctx, int64_t key_id) {
GGML_ASSERT(key_id >= 0 && key_id < gguf_get_n_kv(ctx));
+8
View File
@@ -577,6 +577,10 @@ static bool handcrafted_check_kv(const gguf_context * gguf_ctx, const unsigned i
ok = false;
continue;
}
if (gguf_get_arr_str_len(gguf_ctx, id, 0) != n) { // a string KV pair has a single element
ok = false;
continue;
}
if (!std::equal(str, str + n, data8)) {
ok = false;
}
@@ -602,6 +606,10 @@ static bool handcrafted_check_kv(const gguf_context * gguf_ctx, const unsigned i
ok = false;
continue;
}
if (gguf_get_arr_str_len(gguf_ctx, id, istr) != n) {
ok = false;
continue;
}
const char * str_expected = reinterpret_cast<const char *>(&data[istr]);
if (strncmp(str, str_expected, n) != 0) {
ok = false;