Skip to content

addLog escaping only replaces first occurrence and backtick escape is a no-op #4645

@ShehabSherif0

Description

@ShehabSherif0

The addLog methods in InlineEditRequestLogContext and DiagnosticInlineEditRequestLogContext use String.prototype.replace() with a string first argument to escape special characters before writing to the markdown log output. This only replaces the first occurrence of each character, not all of them.

Additionally, the backtick replacement .replace('', '`')is a complete no-op because'`'is not a recognized JavaScript escape sequence. The backslash is silently dropped, so the replacement string evaluates to just `` (a plain backtick). The intended behavior was to produce `\ to escape backticks for markdown safety.

Affected files:

  • src/platform/inlineEdits/common/inlineEditLogContext.ts (line 574)
  • src/extension/inlineEdits/vscode-node/features/diagnosticsBasedCompletions/diagnosticsCompletions.ts (line 153)

Buggy code (identical in both files):

this._logs.push(content.replace('\n', '\\n').replace('\t', '\\t').replace('`', '\`') + '\n');

Three bugs in one line:

  1. .replace('\n', '\\n') only replaces the first newline
  2. .replace('\t', '\\t') only replaces the first tab
  3. .replace('', '`')` replaces backtick with backtick (no-op)

Reproduction (Node.js):

// Bug 1 and 2: only first occurrence replaced
'a\nb\nc'.replace('\n', '\\n')  // => 'a\\nb\nc' (second \n untouched)

// Bug 3: backtick escape is a no-op
'\`' === '`'  // => true (backslash silently dropped)
'a`b`c'.replace('`', '\`')  // => 'a`b`c' (unchanged)

Impact:
When log content contains multiple newlines, tabs, or backticks (for example, error messages with stack traces passed via diagnosticsInlineEditProvider.ts:113), only the first of each is escaped. Raw newlines break the log line structure, raw tabs produce unexpected whitespace, and unescaped backticks can corrupt the surrounding markdown rendering in the inline edit debug panels.

Fix:
Use regex literals with the global flag, and use a properly escaped replacement string for backticks:

this._logs.push(content.replace(/\n/g, '\\n').replace(/\t/g, '\\t').replace(/`/g, '\\`') + '\n');

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions