Frun1na opened a new issue, #6821: URL: https://github.com/apache/rocketmq-dashboard/issues/6821
### Before Creating the Bug Report - [x] I have searched the [open issues](https://github.com/apache/rocketmq-dashboard/issues) of this repository and believe that this is not a duplicate. - [x] This is a defect in RocketMQ Studio, not a usage question and not a defect in another Apache RocketMQ repository. - [x] I can reproduce this on the current `rocketmq-studio` branch, or I have stated the exact version I am running below. ### Studio Version branch: rocketmq-studio git commit id: a92c2314 deployed as: reproduced by a unit test against that commit ### Runtime Environment OS: not applicable — the defect is in the frontend prompt-template store MySQL: not applicable — the defect is in the frontend prompt-template store browser (for UI issues): not required to observe it; the stored value itself carries half a character, and the failing assertion prints it as the replacement glyph ### Connected RocketMQ Cluster not applicable — the template store is client-side only and no run is started by this path. ### Describe the Bug Saving a prompt template clamps its text with `String.prototype.slice`, which can cut between the two UTF-16 halves of a supplementary character: the saved title, tag or body then ends in a lone high surrogate, i.e. half of the emoji the operator typed. The save path is `saveCustomPromptTemplate` (`web/src/pages/ai/promptTemplates.ts:336-360`; the title at `:341` and the body at `:342`), which clamps the title to `MAX_PROMPT_TEMPLATE_TITLE_LENGTH` (80), the body to `MAX_PROMPT_TEMPLATE_BODY_LENGTH` (6000), each tag to 24 through `normalizeTags`, and — on the way back in — every stored field through `sanitizeCustomTemplate`. All of them go through one helper: ```ts const normalizeText = (value: unknown, maxLength: number): string => { const text = typeof value === 'string' ? value.trim() : ''; return text.length > maxLength ? text.slice(0, maxLength) : text; }; ``` `length` and `slice` count UTF-16 units, while an emoji is one character in two of them. A title of 79 `a`s followed by `🚀` is 81 units, so the cap keeps the 79 `a`s **and the emoji's high surrogate** (`\uD83D`) and drops the low one: the template is stored — and rendered by the modal at `PromptTemplateModal.tsx:275` — with an unpaired surrogate, which every consumer displays as the replacement glyph. The tail of the title is destroyed and the operator sees `aaaa…�` instead of their own text. The same cut already has a merged fix in this subsystem: #5213 routed the conversation title through `TextBounds.truncate` for exactly this reason (`AiConversationService.java:351-357`), because "a title ending in a supplementary character stored a lone high surrogate". The prompt-template caps were the copy that PR did not cover. ### Steps to Reproduce Through the store: ```text saveCustomPromptTemplate({ title: `${'a'.repeat(79)}🚀`, body: 'inspect the broker' }) ``` Through the UI: open the AI page, expand the template panel, paste a title of 79 characters followed by an emoji into 模板标题 — that input carries no `maxLength` — and save. The saved card renders the title with a replacement glyph where the emoji was. The regression test in the pull request pins both this and the body cap (5999 units followed by an emoji) and fails against the current branch. ### What Did You Expect to See? The clamp keeps whole characters: a supplementary character that would straddle the cap is dropped entirely, the way `TextBounds.truncate` drops it on the server, so the saved title is 79 `a`s and the stored string contains no unpaired surrogate. ### What Did You See Instead? The saved title was 79 `a`s plus the emoji's high surrogate. The stored value is not a valid character sequence, and the template list renders the replacement glyph at the end of the title; applying the template then puts that broken character into the prompt as well. ### Additional Context A fix with a regression test follows in a pull request. ### Are You Willing to Submit a Pull Request? - [x] Yes, I am willing to submit a pull request. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
