fix: Replace jsdom for detecting html with more lightweight lib (no-changelog) (#18188)

This commit is contained in:
Michael Kret
2025-08-11 17:03:41 +03:00
committed by GitHub
parent 660f2ff09b
commit 58df26c70b
4 changed files with 52 additions and 16 deletions

View File

@@ -55,10 +55,10 @@
"fast-glob": "catalog:",
"file-type": "16.5.4",
"form-data": "catalog:",
"htmlparser2": "^10.0.0",
"http-proxy-agent": "catalog:",
"https-proxy-agent": "catalog:",
"iconv-lite": "catalog:",
"jsdom": "23.0.1",
"jsonwebtoken": "catalog:",
"lodash": "catalog:",
"luxon": "catalog:",

View File

@@ -6,6 +6,7 @@ import { Readable } from 'stream';
import {
bufferEscapeHtml,
createHtmlSandboxTransformStream,
hasHtml,
isHtmlRenderedContentType,
sandboxHtmlResponse,
} from '../html-sandbox';
@@ -373,3 +374,21 @@ describe('sandboxHtmlResponse > sandboxing disabled', () => {
expect(sandboxHtmlResponse(data)).toEqual(data);
});
});
describe('hasHtml', () => {
test('returns true for valid HTML', () => {
expect(hasHtml('<p>Hello</p>')).toBe(true);
});
test('returns true for malformed but still HTML-like content', () => {
expect(hasHtml('<div><span>Test')).toBe(true);
});
test('returns false for plain text', () => {
expect(hasHtml('Just a string')).toBe(false);
});
test('returns false for empty string', () => {
expect(hasHtml('')).toBe(false);
});
});

View File

@@ -1,6 +1,6 @@
import { SecurityConfig } from '@n8n/config';
import { Container } from '@n8n/di';
import { JSDOM } from 'jsdom';
import { ElementType, parseDocument } from 'htmlparser2';
import type { TransformCallback } from 'stream';
import { Transform } from 'stream';
@@ -13,10 +13,8 @@ export const isIframeSandboxDisabled = () => {
*/
export const hasHtml = (str: string) => {
try {
const dom = new JSDOM(str);
return (
dom.window.document.body.children.length > 0 || dom.window.document.head.children.length > 0
);
const doc = parseDocument(str);
return doc.children.some((node) => node.type === ElementType.Tag);
} catch {
return false;
}