mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-25 10:19:33 +00:00
fix(msteams): decode & last in stripHtmlFromTeamsMessage to avoid double-decoding (#96342)
stripHtmlFromTeamsMessage decoded & FIRST, so literal entity text the user typed (which Microsoft Graph returns double-encoded, e.g. &lt;) got re-decoded into markup: "The token is &lt;APIKEY&gt;" became "The token is <APIKEY>" instead of the correct "The token is <APIKEY>". Reorder so & is decoded last, mirroring the documented ordering in decodeHtmlEntities (inbound.ts), whose comment already states it 'must be last to prevent double-decoding (e.g. &lt; -> < not <)'. Behavior-preserving for all singly-encoded input; the existing entity test is unchanged. Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -37,6 +37,15 @@ describe("stripHtmlFromTeamsMessage", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("does not double-decode escaped entities (decodes & last)", () => {
|
||||
// Graph encodes literally-typed entity text by escaping its '&' to '&'.
|
||||
// Decoding '&' first would re-decode the now-bare '<'/'>' into
|
||||
// angle brackets, corrupting the user's literal text.
|
||||
expect(stripHtmlFromTeamsMessage("The token is &lt;APIKEY&gt;")).toBe(
|
||||
"The token is <APIKEY>",
|
||||
);
|
||||
});
|
||||
|
||||
it("normalizes multiple whitespace to single space", () => {
|
||||
expect(stripHtmlFromTeamsMessage("hello world")).toBe("hello world");
|
||||
});
|
||||
|
||||
@@ -35,14 +35,16 @@ export function stripHtmlFromTeamsMessage(html: string): string {
|
||||
let text = html.replace(/<at[^>]*>(.*?)<\/at>/gi, "@$1");
|
||||
// Strip remaining HTML tags.
|
||||
text = text.replace(/<[^>]*>/g, " ");
|
||||
// Decode common HTML entities.
|
||||
// Decode common HTML entities. & must be decoded LAST to prevent
|
||||
// double-decoding (e.g. &lt; → < not <), matching decodeHtmlEntities
|
||||
// in inbound.ts.
|
||||
text = text
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, "'")
|
||||
.replace(/ /g, " ");
|
||||
.replace(/ /g, " ")
|
||||
.replace(/&/g, "&");
|
||||
// Normalize whitespace.
|
||||
return text.replace(/\s+/g, " ").trim();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user