Skip to content
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 34 additions & 22 deletions src/lib/stores/tts.svelte.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,41 @@
const SUPPORTED = typeof window !== 'undefined' && 'speechSynthesis' in window;

/** Remove all HTML tags, repeating until no tags remain (prevents incomplete sanitization). */
function stripHtmlTags(text: string): string {
const tagPattern = /<[^>]*>/g;
let previous = text;
let result = text.replace(tagPattern, '');

Check failure

Code scanning / CodeQL

Incomplete multi-character sanitization High

This string may still contain
<script
, which may cause an HTML element injection vulnerability.
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
while (result !== previous) {
previous = result;
result = result.replace(tagPattern, '');
}
return result;
}

/** Strip markdown/HTML to plain text suitable for speech synthesis. */
function stripToPlainText(markdown: string): string {
return markdown
// Remove code blocks (``` ... ```)
.replace(/```[\s\S]*?```/g, ' code block omitted ')
// Remove inline code
.replace(/`([^`]+)`/g, '$1')
// Remove images
.replace(/!\[([^\]]*)\]\([^)]+\)/g, '$1')
// Remove links — keep text
.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
// Remove headings markers
.replace(/^#{1,6}\s+/gm, '')
// Remove bold/italic markers
.replace(/\*{1,3}([^*]+)\*{1,3}/g, '$1')
.replace(/_{1,3}([^_]+)_{1,3}/g, '$1')
// Remove strikethrough
.replace(/~~([^~]+)~~/g, '$1')
// Remove blockquotes
.replace(/^>\s+/gm, '')
// Remove horizontal rules
.replace(/^[-*_]{3,}\s*$/gm, '')
// Remove HTML tags
.replace(/<[^>]+>/g, '')
return stripHtmlTags(
markdown
// Remove code blocks (``` ... ```)
.replace(/```[\s\S]*?```/g, ' code block omitted ')
// Remove inline code
.replace(/`([^`]+)`/g, '$1')
// Remove images
.replace(/!\[([^\]]*)\]\([^)]+\)/g, '$1')
// Remove links — keep text
.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
// Remove headings markers
.replace(/^#{1,6}\s+/gm, '')
// Remove bold/italic markers
.replace(/\*{1,3}([^*]+)\*{1,3}/g, '$1')
.replace(/_{1,3}([^_]+)_{1,3}/g, '$1')
// Remove strikethrough
.replace(/~~([^~]+)~~/g, '$1')
// Remove blockquotes
.replace(/^>\s+/gm, '')
// Remove horizontal rules
.replace(/^[-*_]{3,}\s*$/gm, '')
)
// Collapse multiple newlines/spaces
.replace(/\n{2,}/g, '. ')
.replace(/\n/g, ' ')
Expand Down
Loading