From be0906a6c73726ed02a358bcbe904fa3d99713ea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?=
 <67428053+kakkokari-gtyih@users.noreply.github.com>
Date: Sun, 15 Sep 2024 12:30:27 +0900
Subject: [PATCH] =?UTF-8?q?fix(backend):=20happy-dom=E3=81=A7=E5=A4=96?=
 =?UTF-8?q?=E9=83=A8HTML=E3=82=92=E3=83=91=E3=83=BC=E3=82=B9=E3=81=99?=
 =?UTF-8?q?=E3=82=8B=E9=9A=9B=E3=81=AB=E9=96=A2=E9=80=A3=E3=83=AA=E3=82=BD?=
 =?UTF-8?q?=E3=83=BC=E3=82=B9=E3=81=8C=E8=AA=AD=E3=81=BF=E8=BE=BC=E3=81=BE?=
 =?UTF-8?q?=E3=82=8C=E3=82=8B=E5=95=8F=E9=A1=8C=E3=82=92=E4=BF=AE=E6=AD=A3?=
 =?UTF-8?q?=20(#14521)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* bump happy-dom, disable all JS&c when parsing

version 10 didn't quite support disabling all of that

I have tested that `MfmService` (the other code that uses `happy-dom`)
still works fine: the RSS feed for a user is generated correctly, with
HTML rendered from MFM

(cherry picked from commit 26e0412fbb91447c37e8fb06ffb0487346063bb8)

* Update Changelog

* lint

* fix possible memory leak

---------

Co-authored-by: dakkar <dakkar@thenautilus.net>
---
 CHANGELOG.md                                  |  2 +
 packages/backend/package.json                 |  2 +-
 .../src/core/activitypub/ApRequestService.ts  | 39 +++++++++++++++----
 pnpm-lock.yaml                                | 14 ++++++-
 4 files changed, 47 insertions(+), 10 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index e1d92e01cc..bc2d9f102e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,8 @@
 
 ### Server
 - Fix: ファイルがサイズの制限を超えてアップロードされた際にエラーを返さなかった問題を修正
+- Fix: 外部ページを解析する際に、ページに紐づけられた関連リソースも読み込まれてしまう問題を修正  
+  (Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/commit/26e0412fbb91447c37e8fb06ffb0487346063bb8)
 
 
 ## 2024.8.0
diff --git a/packages/backend/package.json b/packages/backend/package.json
index f497610af9..797eddcf7d 100644
--- a/packages/backend/package.json
+++ b/packages/backend/package.json
@@ -119,7 +119,7 @@
 		"fluent-ffmpeg": "2.1.3",
 		"form-data": "4.0.0",
 		"got": "14.4.2",
-		"happy-dom": "10.0.3",
+		"happy-dom": "15.6.1",
 		"hpagent": "1.2.0",
 		"htmlescape": "1.1.1",
 		"http-link-header": "1.1.3",
diff --git a/packages/backend/src/core/activitypub/ApRequestService.ts b/packages/backend/src/core/activitypub/ApRequestService.ts
index 7cf8359212..805280db36 100644
--- a/packages/backend/src/core/activitypub/ApRequestService.ts
+++ b/packages/backend/src/core/activitypub/ApRequestService.ts
@@ -207,16 +207,41 @@ export class ApRequestService {
 
 		if ((contentType ?? '').split(';')[0].trimEnd().toLowerCase() === 'text/html' && _followAlternate === true) {
 			const html = await res.text();
-			const window = new Window();
+			const window = new Window({
+				settings: {
+					disableJavaScriptEvaluation: true,
+					disableJavaScriptFileLoading: true,
+					disableCSSFileLoading: true,
+					disableComputedStyleRendering: true,
+					handleDisabledFileLoadingAsSuccess: true,
+					navigation: {
+						disableMainFrameNavigation: true,
+						disableChildFrameNavigation: true,
+						disableChildPageNavigation: true,
+						disableFallbackToSetURL: true,
+					},
+					timer: {
+						maxTimeout: 0,
+						maxIntervalTime: 0,
+						maxIntervalIterations: 0,
+					},
+				},
+			});
 			const document = window.document;
-			document.documentElement.innerHTML = html;
+			try {
+				document.documentElement.innerHTML = html;
 
-			const alternate = document.querySelector('head > link[rel="alternate"][type="application/activity+json"]');
-			if (alternate) {
-				const href = alternate.getAttribute('href');
-				if (href) {
-					return await this.signedGet(href, user, false);
+				const alternate = document.querySelector('head > link[rel="alternate"][type="application/activity+json"]');
+				if (alternate) {
+					const href = alternate.getAttribute('href');
+					if (href) {
+						return await this.signedGet(href, user, false);
+					}
 				}
+			} catch (e) {
+				// something went wrong parsing the HTML, ignore the whole thing
+			} finally {
+				window.close();
 			}
 		}
 		//#endregion
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 60842367fb..3e5250ce7e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -246,8 +246,8 @@ importers:
         specifier: 14.4.2
         version: 14.4.2
       happy-dom:
-        specifier: 10.0.3
-        version: 10.0.3
+        specifier: 15.6.1
+        version: 15.6.1
       hpagent:
         specifier: 1.2.0
         version: 1.2.0
@@ -7782,6 +7782,10 @@ packages:
   happy-dom@10.0.3:
     resolution: {integrity: sha512-WkCP+Z5fX6U5PY+yHP3ElV5D9PoxRAHRWPFq3pG9rg/6Hjf5ak7dozAgSCywsTRUq2qfa8vV8OQvUy5pRXy8EQ==}
 
+  happy-dom@15.6.1:
+    resolution: {integrity: sha512-dsMHLsJHZYhXeExP47B2siAfKNVxptlwFss3/bq/9sG3iBt0P2WYFBq68JgMR5vB5gsN2Ev0feTTPD/+rosUNQ==}
+    engines: {node: '>=18.0.0'}
+
   har-schema@2.0.0:
     resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==}
     engines: {node: '>=4'}
@@ -20289,6 +20293,12 @@ snapshots:
       whatwg-encoding: 2.0.0
       whatwg-mimetype: 3.0.0
 
+  happy-dom@15.6.1:
+    dependencies:
+      entities: 4.5.0
+      webidl-conversions: 7.0.0
+      whatwg-mimetype: 3.0.0
+
   har-schema@2.0.0: {}
 
   har-validator@5.1.5: