Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix 'trusted-replace-node-text' — output literal quotes for escaped quotes #440

Open
Yuki2718 opened this issue Aug 5, 2024 · 5 comments
Assignees
Labels
bug Something isn't working Priority: P4

Comments

@Yuki2718
Copy link

Yuki2718 commented Aug 5, 2024

Filters like

exploader.net#%#//scriptlet('trusted-replace-node-text', 'script', 'ダウンロード', '/(window\.[0-9A-z]+[\S\s]+ele\.outerHTML;\})/', '$1;document.addEventListener("DOMContentLoaded", (async function(){const t="undefined"!=typeof dl_link?Object.values(dl_link):null,e=document.querySelector(\'a.dl_button[href*="?"]\');if(!t||!e)return;const n=e.getAttribute("href");let l=null;t.forEach((async t=>{const e=n.replace(/\?.*/,`?${t}`);await(async t=>{const e=await fetch(t);return!(await e.text()).includes("広告ブロック")})(e)&&(l=t,document.querySelectorAll(\'a.dl_button[href*="?"]\').forEach((t=>{let e=t.getAttribute("href");e=e.replace(/\?.*/,`?${l}`),t.setAttribute("href",e)})))}))}))')

outputs literal \' and not ' so can't be used.

@Yuki2718
Copy link
Author

Yuki2718 commented Aug 5, 2024

Somewhat related but different: #286

@slavaleleka
Copy link
Contributor

if single quotes are used to wrap a scriptlet parameter, the same single quote should be escaped inside the parameter:

valid:
'prop[\'nested\']'
not valid:
'prop['nested']'
https://github.com/AdguardTeam/Scriptlets?tab=readme-ov-file#scriptlet-syntax

@Yuki2718
Copy link
Author

Yuki2718 commented Aug 5, 2024

So how to make

exploader.net#%#//scriptlet('trusted-replace-node-text', 'script', 'ダウンロード', '/(window\.[0-9A-z]+[\S\s]+ele\.outerHTML;\})/', '$1;document.addEventListener("DOMContentLoaded", (async function(){const t="undefined"!=typeof dl_link?Object.values(dl_link):null,e=document.querySelector(\'a.dl_button[href*="?"]\');if(!t||!e)return;const n=e.getAttribute("href");let l=null;t.forEach((async t=>{const e=n.replace(/\?.*/,`?${t}`);await(async t=>{const e=await fetch(t);return!(await e.text()).includes("広告ブロック")})(e)&&(l=t,document.querySelectorAll(\'a.dl_button[href*="?"]\').forEach((t=>{let e=t.getAttribute("href");e=e.replace(/\?.*/,`?${l}`),t.setAttribute("href",e)})))}))}))')

work? Adam proposed a workaround on Slack:

exploader.net#%#//scriptlet('trusted-replace-node-text', 'script', 'ダウンロード', '/(window\.[0-9A-z]+[\S\s]+ele\.outerHTML;\})/', '$1;document.addEventListener("DOMContentLoaded", (async function(){const t="undefined"!=typeof dl_link?Object.values(dl_link):null,e=document.querySelector("a.dl_button[href*=\"?\"]");if(!t||!e)return;const n=e.getAttribute("href");let l=null;t.forEach((async t=>{const e=n.replace(/\?.*/,`?${t}`);await(async t=>{const e=await fetch(t);return!(await e.text()).includes("広告ブロック")})(e)&&(l=t,document.querySelectorAll("a.dl_button[href*=\"?\"]").forEach((t=>{let e=t.getAttribute("href");e=e.replace(/\?.*/,`?${l}`),t.setAttribute("href",e)})))}))}))')

but this really is just a workaround and not the fundamental cure.

@Yuki2718 Yuki2718 changed the title Allow to use quotes inside arguments trusted-replace-node-text should outputs literal quotes for escaped quotes Aug 5, 2024
@ameshkov
Copy link
Member

ameshkov commented Aug 5, 2024

Debug it via browser console, make it a valid JS function call:

var scriptlet = function() {
    console.log('test');
}

scriptlet('trusted-replace-node-text', 'script', 'ダウンロード', '/(window\.[0-9A-z]+[\S\s]+ele\.outerHTML;\})/', '$1;document.addEventListener("DOMContentLoaded", (async function(){const t="undefined"!=typeof dl_link?Object.values(dl_link):null,e=document.querySelector("a.dl_button[href*=\"?\"]");if(!t||!e)return;const n=e.getAttribute("href");let l=null;t.forEach((async t=>{const e=n.replace(/\?.*/,`?${t}`);await(async t=>{const e=await fetch(t);return!(await e.text()).includes("広告ブロック")})(e)&&(l=t,document.querySelectorAll("a.dl_button[href*=\"?\"]").forEach((t=>{let e=t.getAttribute("href");e=e.replace(/\?.*/,`?${l}`),t.setAttribute("href",e)})))}))}))')

@AdamWr
Copy link
Member

AdamWr commented Aug 5, 2024

I think that it's a correct issue.

Simple steps to reproduce:

  1. Add this rule:
fiddle.jshell.net#%#//scriptlet('trusted-replace-node-text', 'script', 'alert', '/alert\(\'test\'\)/', 'alert(\'replaced\')')
  1. Go to - https://jsfiddle.net/6p7eq9an/
<script>
alert('test');
</script>

It should replaces alert('test') with alert('replaced') but it changes it to alert(\'replaced\'), so script is broken and alert is not displayed.

Screenshot

image

@slavaleleka slavaleleka reopened this Aug 5, 2024
@adguard-bot adguard-bot changed the title trusted-replace-node-text should outputs literal quotes for escaped quotes Fix 'trusted-replace-node-text' — output literal quotes for escaped quotes Aug 5, 2024
@slavaleleka slavaleleka added the bug Something isn't working label Oct 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Priority: P4
Projects
None yet
Development

No branches or pull requests

6 participants