File tree Expand file tree Collapse file tree 2 files changed +19
-3
lines changed
Expand file tree Collapse file tree 2 files changed +19
-3
lines changed Original file line number Diff line number Diff line change @@ -32,7 +32,7 @@ export function parseBoolean(candidate: string | number) {
3232 * - Complex nested quotes or edge cases may not be handled perfectly
3333 * - For more complex HTML sanitization needs, consider using a proper HTML parser
3434 *
35- * @param {string } text - The text to sanitize. Can be null or undefined.
35+ * @param {string | null | undefined } text - The text to sanitize. Can be null or undefined.
3636 * @returns {string } The sanitized text safe for HTML rendering, or the original value if null/undefined.
3737 *
3838 * @example
@@ -42,7 +42,7 @@ export function parseBoolean(candidate: string | number) {
4242 * sanitizeTextForRender('Price < $100 <strong>Sale!</strong>') // 'Price < $100 <strong>Sale!</strong>'
4343 */
4444export function sanitizeTextForRender ( text : string | null | undefined ) {
45- if ( ! text ) return text ;
45+ if ( ! text ) return '' ;
4646
4747 return (
4848 text
@@ -72,8 +72,9 @@ export function sanitizeTextForRender(text: string | null | undefined) {
7272 // \s+ - whitespace before attributes
7373 // [^>]* - any characters except '>' (attribute content)
7474 // )? - attributes are optional
75+ // \/? - optional self-closing slash before >
7576 // ) - end lookbehind
7677 // > - matches '>'
77- . replace ( / (?< ! < \/ ? \w + (?: \s + [ ^ > ] * ) ? ) > / g, '>' )
78+ . replace ( / (?< ! < \/ ? \w + (?: \s + [ ^ > ] * ) ? \/ ? ) > / g, '>' )
7879 ) ;
7980}
Original file line number Diff line number Diff line change @@ -148,4 +148,19 @@ describe('#sanitizeTextForRender', () => {
148148 const expected = `Original message:<br>> User wrote: x < 5<br><blockquote>Previous reply</blockquote>` ;
149149 expect ( sanitizeTextForRender ( quoted ) ) . toBe ( expected ) ;
150150 } ) ;
151+
152+ it ( 'should handle self-closing tags correctly' , ( ) => {
153+ expect ( sanitizeTextForRender ( '<br />' ) ) . toBe ( '<br />' ) ;
154+ expect ( sanitizeTextForRender ( '<img src="test.jpg" />' ) ) . toBe ( '<img src="test.jpg" />' ) ;
155+ expect ( sanitizeTextForRender ( '<input type="text" value="test" />' ) ) . toBe ( '<input type="text" value="test" />' ) ;
156+ expect ( sanitizeTextForRender ( '<hr/>' ) ) . toBe ( '<hr/>' ) ;
157+ expect ( sanitizeTextForRender ( 'Text before <br /> text after' ) ) . toBe ( 'Text before <br /> text after' ) ;
158+ expect ( sanitizeTextForRender ( '<meta charset="UTF-8" />' ) ) . toBe ( '<meta charset="UTF-8" />' ) ;
159+ } ) ;
160+
161+ it ( 'should handle complex URLs in attributes' , ( ) => {
162+ expect ( sanitizeTextForRender ( '<img src="https://example.com/image.jpg?width=100&height=200&format=webp" />' ) ) . toBe ( '<img src="https://example.com/image.jpg?width=100&height=200&format=webp" />' ) ;
163+ expect ( sanitizeTextForRender ( '<a href="https://api.example.com/v2/users/123/profile?include=posts&sort=desc">Profile</a>' ) ) . toBe ( '<a href="https://api.example.com/v2/users/123/profile?include=posts&sort=desc">Profile</a>' ) ;
164+ expect ( sanitizeTextForRender ( '<iframe src="//cdn.example.com/embed/video/12345?autoplay=1&loop=0" />' ) ) . toBe ( '<iframe src="//cdn.example.com/embed/video/12345?autoplay=1&loop=0" />' ) ;
165+ } ) ;
151166} ) ;
You can’t perform that action at this time.
0 commit comments