Skip to content

perf: replace empty functions with noopQrl#6871

Closed
wmertens wants to merge 2 commits intobuild/v2from
optimizer-noop
Closed

perf: replace empty functions with noopQrl#6871
wmertens wants to merge 2 commits intobuild/v2from
optimizer-noop

Conversation

@wmertens
Copy link
Member

@wmertens wmertens commented Sep 8, 2024

This is a fairly trivial improvement, but it does avoid loading empty functions on the client.

To make it work, I needed to run the simplification twice (before and after segmentation) but it's still fast.

TODO:

  • don't remove code in server before scope captures are recorded
  • make the qrl serialization skip client noopQrl, perhaps by emitting "noop" segment info from the client transform

@wmertens wmertens self-assigned this Sep 8, 2024
@wmertens wmertens requested a review from a team as a code owner September 8, 2024 10:20
@changeset-bot
Copy link

changeset-bot bot commented Sep 8, 2024

⚠️ No Changeset found

Latest commit: 9e87449

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@wmertens
Copy link
Member Author

wmertens commented Sep 8, 2024

hmm the e2e aren't happy :(

c.push(`\n/** Qwik Router Entries (${entries.length}) */`);
for (let i = 0; i < entries.length; i++) {
const entry = entries[i];
c.push(`export const ${entry.id} = () => import(${JSON.stringify(entry.filePath)});`);

Check warning

Code scanning / CodeQL

Improper code sanitization

Code construction depends on an [improperly sanitized value](1).

Copilot Autofix

AI about 1 year ago

To fix the problem, we need to ensure that any potentially dangerous characters in entry.filePath are properly escaped before being included in the generated JavaScript code. We can achieve this by implementing a function that escapes these characters and using it to sanitize entry.filePath.

  • Implement a function escapeUnsafeChars that escapes potentially dangerous characters.
  • Use this function to sanitize entry.filePath before including it in the generated code.
Suggested changeset 1
packages/qwik-router/src/buildtime/runtime-generation/generate-entries.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/packages/qwik-router/src/buildtime/runtime-generation/generate-entries.ts b/packages/qwik-router/src/buildtime/runtime-generation/generate-entries.ts
--- a/packages/qwik-router/src/buildtime/runtime-generation/generate-entries.ts
+++ b/packages/qwik-router/src/buildtime/runtime-generation/generate-entries.ts
@@ -2,2 +2,20 @@
 
+function escapeUnsafeChars(str: string): string {
+  const charMap: { [key: string]: string } = {
+    '<': '\\u003C',
+    '>': '\\u003E',
+    '/': '\\u002F',
+    '\\': '\\\\',
+    '\b': '\\b',
+   '\f': '\\f',
+   '\n': '\\n',
+   '\r': '\\r',
+   '\t': '\\t',
+   '\0': '\\0',
+   '\u2028': '\\u2028',
+   '\u2029': '\\u2029'
+ };
+ return str.replace(/[<>\b\f\n\r\t\0\u2028\u2029]/g, x => charMap[x]);
+}
+
 export function createEntries(ctx: BuildContext, c: string[]) {
@@ -25,3 +43,3 @@
     const entry = entries[i];
-    c.push(`export const ${entry.id} = () => import(${JSON.stringify(entry.filePath)});`);
+    c.push(`export const ${entry.id} = () => import(${escapeUnsafeChars(JSON.stringify(entry.filePath))});`);
   }
EOF
@@ -2,2 +2,20 @@

function escapeUnsafeChars(str: string): string {
const charMap: { [key: string]: string } = {
'<': '\\u003C',
'>': '\\u003E',
'/': '\\u002F',
'\\': '\\\\',
'\b': '\\b',
'\f': '\\f',
'\n': '\\n',
'\r': '\\r',
'\t': '\\t',
'\0': '\\0',
'\u2028': '\\u2028',
'\u2029': '\\u2029'
};
return str.replace(/[<>\b\f\n\r\t\0\u2028\u2029]/g, x => charMap[x]);
}

export function createEntries(ctx: BuildContext, c: string[]) {
@@ -25,3 +43,3 @@
const entry = entries[i];
c.push(`export const ${entry.id} = () => import(${JSON.stringify(entry.filePath)});`);
c.push(`export const ${entry.id} = () => import(${escapeUnsafeChars(JSON.stringify(entry.filePath))});`);
}
Copilot is powered by AI and may make mistakes. Always verify output.
}
errorDiv.setAttribute('q:key', '_error_');
const journal: VNodeJournal = [];
vnode_getDOMChildNodes(journal, vHost).forEach((child) => errorDiv.appendChild(child));

Check warning

Code scanning / CodeQL

DOM text reinterpreted as HTML

[DOM text](1) is reinterpreted as HTML without escaping meta-characters. [DOM text](2) is reinterpreted as HTML without escaping meta-characters. [DOM text](3) is reinterpreted as HTML without escaping meta-characters. [DOM text](4) is reinterpreted as HTML without escaping meta-characters. [DOM text](5) is reinterpreted as HTML without escaping meta-characters. [DOM text](6) is reinterpreted as HTML without escaping meta-characters.

Copilot Autofix

AI about 1 year ago

Copilot could not generate an autofix suggestion

Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.

}

if (key === dangerouslySetInnerHTML) {
element.innerHTML = value as string;

Check warning

Code scanning / CodeQL

DOM text reinterpreted as HTML

[DOM text](1) is reinterpreted as HTML without escaping meta-characters.

Copilot Autofix

AI about 1 year ago

To fix this issue, we need to ensure that the value assigned to element.innerHTML is properly sanitized to prevent XSS attacks. The best way to do this is to use a function that escapes HTML special characters before assigning the value to innerHTML.

  1. Import or define an HTML escaping function if not already available.
  2. Use this function to sanitize value before assigning it to element.innerHTML.
Suggested changeset 1
packages/qwik/src/core/client/vnode-diff.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/packages/qwik/src/core/client/vnode-diff.ts b/packages/qwik/src/core/client/vnode-diff.ts
--- a/packages/qwik/src/core/client/vnode-diff.ts
+++ b/packages/qwik/src/core/client/vnode-diff.ts
@@ -669,3 +669,3 @@
         if (key === dangerouslySetInnerHTML) {
-          element.innerHTML = value as string;
+          element.innerHTML = escapeHTML(value as string);
           element.setAttribute(QContainerAttr, QContainerValue.HTML);
EOF
@@ -669,3 +669,3 @@
if (key === dangerouslySetInnerHTML) {
element.innerHTML = value as string;
element.innerHTML = escapeHTML(value as string);
element.setAttribute(QContainerAttr, QContainerValue.HTML);
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
} else if (key === 'value' && key in element) {
(element as any).value = escapeHTML(String(value));
} else if (key === dangerouslySetInnerHTML) {
(element as any).innerHTML = value!;

Check warning

Code scanning / CodeQL

DOM text reinterpreted as HTML

[DOM text](1) is reinterpreted as HTML without escaping meta-characters. [DOM text](2) is reinterpreted as HTML without escaping meta-characters. [DOM text](3) is reinterpreted as HTML without escaping meta-characters. [DOM text](4) is reinterpreted as HTML without escaping meta-characters. [DOM text](5) is reinterpreted as HTML without escaping meta-characters. [DOM text](6) is reinterpreted as HTML without escaping meta-characters.

Copilot Autofix

AI about 1 year ago

To fix the problem, we need to ensure that any value assigned to innerHTML is properly sanitized to prevent XSS attacks. This can be achieved by using a library like DOMPurify to sanitize the HTML content before assigning it to innerHTML.

  • Import the DOMPurify library.
  • Use DOMPurify.sanitize to sanitize the value before assigning it to innerHTML.
Suggested changeset 2
packages/qwik/src/core/client/vnode.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/packages/qwik/src/core/client/vnode.ts b/packages/qwik/src/core/client/vnode.ts
--- a/packages/qwik/src/core/client/vnode.ts
+++ b/packages/qwik/src/core/client/vnode.ts
@@ -120,2 +120,3 @@
 import { isDev } from '@qwik.dev/core/build';
+import DOMPurify from 'dompurify';
 import { qwikDebugToString } from '../debug';
@@ -895,3 +896,3 @@
         } else if (key === dangerouslySetInnerHTML) {
-          (element as any).innerHTML = value!;
+          (element as any).innerHTML = DOMPurify.sanitize(value!);
         } else {
EOF
@@ -120,2 +120,3 @@
import { isDev } from '@qwik.dev/core/build';
import DOMPurify from 'dompurify';
import { qwikDebugToString } from '../debug';
@@ -895,3 +896,3 @@
} else if (key === dangerouslySetInnerHTML) {
(element as any).innerHTML = value!;
(element as any).innerHTML = DOMPurify.sanitize(value!);
} else {
packages/qwik/package.json
Outside changed files

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/packages/qwik/package.json b/packages/qwik/package.json
--- a/packages/qwik/package.json
+++ b/packages/qwik/package.json
@@ -10,3 +10,4 @@
   "dependencies": {
-    "csstype": "^3.1"
+    "csstype": "^3.1",
+    "dompurify": "^3.2.4"
   },
EOF
@@ -10,3 +10,4 @@
"dependencies": {
"csstype": "^3.1"
"csstype": "^3.1",
"dompurify": "^3.2.4"
},
This fix introduces these dependencies
Package Version Security advisories
dompurify (npm) 3.2.4 None
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
const insertBefore = journal[idx++] as Element | Text | null;
let newChild: any;
while (idx < length && typeof (newChild = journal[idx]) !== 'number') {
insertParent.insertBefore(newChild, insertBefore);

Check warning

Code scanning / CodeQL

DOM text reinterpreted as HTML

[DOM text](1) is reinterpreted as HTML without escaping meta-characters. [DOM text](2) is reinterpreted as HTML without escaping meta-characters. [DOM text](3) is reinterpreted as HTML without escaping meta-characters. [DOM text](4) is reinterpreted as HTML without escaping meta-characters. [DOM text](5) is reinterpreted as HTML without escaping meta-characters. [DOM text](6) is reinterpreted as HTML without escaping meta-characters.

Copilot Autofix

AI about 1 year ago

To fix the problem, we need to ensure that any text content being inserted into the DOM is properly escaped to prevent XSS attacks. This can be achieved by using a function that escapes HTML special characters before inserting the content.

  • We will use the escapeHTML function to escape any text content before it is inserted into the DOM.
  • Specifically, we will modify the vnode_applyJournal function to escape newChild before it is inserted using insertBefore.
Suggested changeset 1
packages/qwik/src/core/client/vnode.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/packages/qwik/src/core/client/vnode.ts b/packages/qwik/src/core/client/vnode.ts
--- a/packages/qwik/src/core/client/vnode.ts
+++ b/packages/qwik/src/core/client/vnode.ts
@@ -925,2 +925,5 @@
         while (idx < length && typeof (newChild = journal[idx]) !== 'number') {
+          if (newChild.nodeType === Node.TEXT_NODE) {
+            newChild.nodeValue = escapeHTML(newChild.nodeValue);
+          }
           insertParent.insertBefore(newChild, insertBefore);
EOF
@@ -925,2 +925,5 @@
while (idx < length && typeof (newChild = journal[idx]) !== 'number') {
if (newChild.nodeType === Node.TEXT_NODE) {
newChild.nodeValue = escapeHTML(newChild.nodeValue);
}
insertParent.insertBefore(newChild, insertBefore);
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
@shairez shairez mentioned this pull request Mar 25, 2025
5 tasks
@shairez
Copy link
Contributor

shairez commented May 6, 2025

@wmertens any news on this PR?

note:  reg_ctx_name_segments output is wrong, should include the server qrl
@wmertens
Copy link
Member Author

wmertens commented Mar 5, 2026

closing in favor of #8407

@wmertens wmertens closed this Mar 5, 2026
@Varixo Varixo deleted the optimizer-noop branch March 6, 2026 19:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants