]> git.djapps.eu Git - pkg/ggml/sources/llama.cpp/commitdiff
mtmd: fix silent prompt truncation on embedded NUL (#25548)
authorPascal <redacted>
Sun, 12 Jul 2026 22:47:25 +0000 (00:47 +0200)
committerGitHub <redacted>
Sun, 12 Jul 2026 22:47:25 +0000 (00:47 +0200)
* mtmd: fix silent prompt truncation on embedded NUL

mtmd_input_text carried the prompt as a bare const char* with no
length, so a NUL byte in message content cut the prompt at the
tokenizer boundary and dropped every later message plus the assistant
marker, with no log. Add an explicit text_len and thread it through,
matching llama_tokenize and the text only path.

* cleanup

---------

Co-authored-by: Xuan Son Nguyen <redacted>
tools/mtmd/mtmd-cli.cpp
tools/mtmd/mtmd.cpp
tools/mtmd/mtmd.h
tools/server/server-common.cpp

index 8704ea79d7a076fd60edbbf29a0e714fbf0753c8..08288c868139e3463208a4f0eae0b4ec975e9b36 100644 (file)
@@ -250,7 +250,8 @@ static int eval_message(mtmd_cli_context & ctx, common_chat_msg & msg) {
     LOG_DBG("formatted_chat.prompt: %s\n", formatted_chat.c_str());
 
     mtmd_input_text text;
-    text.text          = formatted_chat.c_str();
+    text.text          = formatted_chat.data();
+    text.text_len      = formatted_chat.size();
     text.add_special   = add_bos;
     text.parse_special = true;
 
index 73270ba889778400119381e3fb67a127374ecb02..e10ccf186b14f8b737292793a4f2bc231b3740c1 100644 (file)
@@ -809,7 +809,7 @@ void mtmd_free(mtmd_context * ctx) {
 struct mtmd_tokenizer {
     mtmd_context * ctx;
 
-    std::string input_text;
+    std::string input_text; // note: can contain null bytes; do not use c_str()
     bool add_special;
     bool parse_special;
     const llama_vocab * vocab;
@@ -839,9 +839,10 @@ struct mtmd_tokenizer {
             size_t n_bitmaps) : ctx(ctx) {
         add_special   = text->add_special;
         parse_special = text->parse_special;
-        input_text    = text->text;
         vocab         = ctx->vocab;
 
+        input_text.assign(text->text, text->text_len);
+
         std::vector<const mtmd_bitmap *> bitmaps(bmps, bmps + n_bitmaps);
         auto parts_str = split_text(input_text, ctx->media_marker);
         size_t i_bm = 0;
index 25d51ef58d4123453e47f2ec462e68673f09dbee..3b8c1200b5665345823d25c5311dd4206c8ae3cc 100644 (file)
@@ -67,6 +67,7 @@ struct mtmd_batch;
 
 struct mtmd_input_text {
     const char * text;
+    size_t text_len;
     bool add_special;
     bool parse_special;
 };
index ac291d359a0c134fd119b3dbe77a26ae4846ce95..c76ed7cc24b3e9905314bf62385850a3b21ee7ea 100644 (file)
@@ -705,7 +705,8 @@ server_tokens process_mtmd_prompt(mtmd_context * mctx, const std::string & promp
     std::vector<server_tokens> inputs;
     // multimodal
     mtmd_input_text inp_txt = {
-        prompt.c_str(),
+        prompt.data(),
+        prompt.size(),
         /* add_special */   true,
         /* parse_special */ true,
     };