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

m.trust carsh in safari - ios 16.3 #2820

Open
0ui0 opened this issue Feb 12, 2023 · 27 comments
Open

m.trust carsh in safari - ios 16.3 #2820

0ui0 opened this issue Feb 12, 2023 · 27 comments
Labels
Type: Question For issues that are purely questions about Mithril, not necessarily bug reports or suggestions

Comments

@0ui0
Copy link

0ui0 commented Feb 12, 2023

Mithril.js version: 2.2.2
Browser and OS: ios16.3 safari

Project: icat

The page is working normal in PC chrome, MAC sarari-16.3 (18614.4.6.1.5),Android chrome(unkown version)
But it carshed in iphone safari-ios16.3

When loading this page, all touch actions will be slow, and after that, the page cahshed.

I debug and find it happend when I use m.trust() to parse the HTML from marked.js

crashed code:

 m.trust(format(self.content,self.contentType))

or

 m.trust(marked(markdownCode))

but not all page crashed,
only the page,
i review the page's markdown, it use normal grammer no special --- no extend HTML.

because it working nomal in other browser

I don't know it is whether or safari's bug
or marked.js bug or mithril.js bug

@0ui0 0ui0 added the Type: Question For issues that are purely questions about Mithril, not necessarily bug reports or suggestions label Feb 12, 2023
@0ui0
Copy link
Author

0ui0 commented Feb 12, 2023

maybe because m.trust include marilto link like this:
abcdefg@abc.com

<a href=mailto:&#97;&#98;&#x63;&#x64;&#101;&#x66;&#103;&#x40;&#x61;&#98;&#x63;&#46;&#99;&#111;&#x6d;  target='_blank'>&#97;&#98;&#x63;&#x64;&#101;&#x66;&#103;&#x40;&#x61;&#98;&#x63;&#46;&#99;&#111;&#x6d;</a>

@pygy
Copy link
Member

pygy commented Feb 12, 2023

Could you share examples of the HTML source that crashes Safari? m.trust() uses innerHTML under the hood, no high magic...

Short of leaking memory from JS, a page shouldn't crash a browser, so it's likely a Safari bug.

It would be nice to see what markup causes it though (what tags, does it contain CSS, etc...).

@0ui0
Copy link
Author

0ui0 commented Feb 12, 2023

Could you share examples of the HTML source that crashes Safari? m.trust() uses innerHTML under the hood, no high magic...

Short of leaking memory from JS, a page shouldn't crash a browser, so it's likely a Safari bug.

It would be nice to see what markup causes it though (what tags, does it contain CSS, etc...).

this is the page
https://www.o-o.space/#!/home/479

I connected my iphone to the mac,
and then copied the source code from the development tools of safari
(this code is in my local environment, different from the web version)

But it is looks hard to read

I wanted to prepare a minimal version that only included the mithril component where the problem was,
but when I isolated the part that I thought might be a bug(only include m.trust(...))

the page works!

but at crashed page, when I remove the m.trust(...),the page works

Too strange

I'll review and check the code again

maybe some other reasons

This code doesn't help the question
I delete the code

@pygy
Copy link
Member

pygy commented Feb 12, 2023

So you're passing a full HTML page to m.trust()?

Wouldn't you be better served by an m("iframe", {srcdoc: yourPageSource}) instead of m.trust(yourPageSource)?

@0ui0
Copy link
Author

0ui0 commented Feb 12, 2023

https://www.o-o.space/#!/home/479

ohh,no no 😂
the m.trust only be used to parse markdown-html-code
as before mentioned like:

<a href=mailto:&#97;&#98;&#x63;&#x64;&#101;&#x66;&#103;&#x40;&#x61;&#98;&#x63;&#46;&#99;&#111;&#x6d;  target='_blank'>&#97;&#98;&#x63;&#x64;&#101;&#x66;&#103;&#x40;&#x61;&#98;&#x63;&#46;&#99;&#111;&#x6d;</a>
m.trust(marked(/*article-start...*/"abcdefg@abc.com"/*article-end...*/))

the HTML-page is the content from safari -> look source code
it rendered by m.mount(...)

i found some other situations:

I checked the code carefully and found that the problem is more complicated than I expected
The following conditions must be met
The safari page will not respond:

  1. The a tag containing mailto must appear in the component of mithril
  2. I use the listener touchstart\touchmove\touchend on my page to control the [pull-down refresh] at the top

In the callback function of these listeners, the m.redraw() function is used to control some changes of the page by modifying the state of some variables

The above two occur at the same time, and the click event running on the safari page will not work normally.

Sorry my previous description wasn't precise enough
The problem page is not completely unresponsive
The problem page can still be scrolled, and mouseover and mouseout can be triggered on the iphone (on the iphone)
But all click events (whether click or touch) are failing

But this situation has not been reproduced under pc chrome, pc Firefox or mac safari, including the mobile development mode of pc chrome, and the chrome of Android phone.

If I use str.replace to remove the mailto tag, or I close the listener of [Pull-down Refresh], if one of them is satisfied, the problem of safari’s unresponsive touch will disappear

@pygy
Copy link
Member

pygy commented Feb 12, 2023

What I'd like to see is the exact input that goes into m.trust(). In other words the return value of marked(/*article-start...*/"abcdefg@abc.com"/*article-end...*/)

@0ui0
Copy link
Author

0ui0 commented Feb 12, 2023

What I'd like to see is the exact input that goes into m.trust(). In other words the return value of marked(/*article-start...*/"abcdefg@abc.com"/*article-end...*/)

console.log(node = m.trust(marked(content)))

Object

attrs: undefined

children: "<p>title test<br><a href=mailto:&#x61;&#98;&#x63;&#x64;&#x65;&#102;&#103;&#64;&#97;&#98;&#x63;&#x2e;&#99;&#x6f;&#x6d;…"

dom: undefined

domSize: undefined

events: undefined

instance: undefined

key: undefined

state: undefined

tag: "<"

text: undefined

console.log(node.children)

<p>title test<br><a href=mailto:&#x61;&#98;&#x63;&#x64;&#x65;&#102;&#103;&#64;&#97;&#98;&#x63;&#x2e;&#99;&#x6f;&#x6d;  target='_blank'>&#x61;&#98;&#x63;&#x64;&#x65;&#102;&#103;&#64;&#97;&#98;&#x63;&#x2e;&#99;&#x6f;&#x6d;</a></p>

console.log(content)

title test
abcdefg@abc.com

console.log(marked(content))

<p>title test<br><a href=mailto:&#x61;&#98;&#x63;&#100;&#x65;&#x66;&#103;&#64;&#x61;&#98;&#x63;&#46;&#99;&#x6f;&#109;  target='_blank'>&#x61;&#98;&#x63;&#100;&#x65;&#x66;&#103;&#64;&#x61;&#98;&#x63;&#46;&#99;&#x6f;&#109;</a></p>

@0ui0
Copy link
Author

0ui0 commented Feb 12, 2023

I use this as temporary solution:

content = content.replace(/([a-zA-Z0-9_]+)@([a-zA-Z0-9_\.]+)\.([a-zA-Z]+)/g,"$1# $2.$3")

@pygy
Copy link
Member

pygy commented Feb 12, 2023

Thanks, this looks completely inoccuous... I don't think Mithril or the HTML is at fault here. At least not the bits you shared. It could cause the planets to align just wrong and trigger a different bug though. Does desktop safari crash too?

If so, could you share the relevant output of the Console app that logs system events? There may be a way to get a remote event log from iOS devices too but I don't know how to do that.

@0ui0
Copy link
Author

0ui0 commented Feb 13, 2023

Thanks, this looks completely inoccuous... I don't think Mithril or the HTML is at fault here. At least not the bits you shared. It could cause the planets to align just wrong and trigger a different bug though. Does desktop safari crash too?

If so, could you share the relevant output of the Console app that logs system events? There may be a way to get a remote event log from iOS devices too but I don't know how to do that.

Yeah, it only crashed in my ios safari -- and recently I update my iphone and ipad to ios 16.3. so i'm not certain it happend in other ios version. But in my Mac's safari, it can runs good.

so i hightly doubt that it is a safari's bug. Because I visit my website everyday, and before my update, I never found the situation. Tough I also update my program recently. But the changed code does not involve these modules.

I link my iphone to my macbook and use devTools check it due to some javascript Error at console, but nothing. I change to the performance tag, check for high cpu or memory usage, but the line is flat.

Because the iphone debugging page is very troublesome, I tried to split the code to single page see if it can be reproduced, but failed, I will continue to follow up and observe this situation

@pygy
Copy link
Member

pygy commented Feb 13, 2023

AFAIK, short of a bug, the only way to crash a browser tab is to exhaust memory.

I don't think that m.trust() can do that. m.trust() alone just creates a vnode. When that vnode is rendered, a temp DOM node is created, we set its innerHTML, then move the children from the temp node to the parent of the trusted vnode.

Does the m.trust() vnode have siblings? If not, you can replace the m.trust() vnode with a oncreate hook that sets innerHTML on the parent node... If the crash still happens, this would exonerate m.trust entirely.

@0ui0
Copy link
Author

0ui0 commented Feb 13, 2023

AFAIK, short of a bug, the only way to crash a browser tab is to exhaust memory.

I don't think that m.trust() can do that. m.trust() alone just creates a vnode. When that vnode is rendered, a temp DOM node is created, we set its innerHTML, then move the children from the temp node to the parent of the trusted vnode.

Does the m.trust() vnode have siblings? If not, you can replace the m.trust() vnode with a oncreate hook that sets innerHTML on the parent node... If the crash still happens, this would exonerate m.trust entirely.

Oh, you may have missed my supplementary instructions. I mentioned that when the two points happen at the same time, it will cause a crash. Using m.trust alone or using touch events will not happen

supplementary instructions

@pygy
Copy link
Member

pygy commented Feb 13, 2023

Indeed I had skipped that bit of your post, sorry.

What if you add a mailto: link statically in the HTML source page? What about a m('a', {href:"mailto:..."}) link instead of the m.trust bit?

Edit: you can encode the email like this:

function htmlEncode(src) {
  return [...src].map(c => `&#${
    Math.random() < 0.5 ? c.codePointAt(0).toString() : "x" + c.codePointAt(0).toString(16)
  };`).join("")
}

marked uses a mix of decimal and hexadecimal html entities escapes.

@0ui0
Copy link
Author

0ui0 commented Feb 14, 2023

Indeed I had skipped that bit of your post, sorry.

What if you add a mailto: link statically in the HTML source page? What about a m('a', {href:"mailto:..."}) link instead of the m.trust bit?

Edit: you can encode the email like this:

function htmlEncode(src) {
  return [...src].map(c => `&#${
    Math.random() < 0.5 ? c.codePointAt(0).toString() : "x" + c.codePointAt(0).toString(16)
  };`).join("")
}

marked uses a mix of decimal and hexadecimal html entities escapes.

I record a video : videoLink
I don't know whether you can look
if not, i will upload to another platform _ (:з」∠)_

@0ui0
Copy link
Author

0ui0 commented Feb 14, 2023

Indeed I had skipped that bit of your post, sorry.

What if you add a mailto: link statically in the HTML source page? What about a m('a', {href:"mailto:..."}) link instead of the m.trust bit?

Edit: you can encode the email like this:

function htmlEncode(src) {
  return [...src].map(c => `&#${
    Math.random() < 0.5 ? c.codePointAt(0).toString() : "x" + c.codePointAt(0).toString(16)
  };`).join("")
}

marked uses a mix of decimal and hexadecimal html entities escapes.

I try to upload to the google drive,but the speed is too slow....

@pygy
Copy link
Member

pygy commented Feb 14, 2023

I can see the video, I'll watch it later today.

@0ui0
Copy link
Author

0ui0 commented Feb 14, 2023

I can see the video, I'll watch it later today.

when I log out i find it can only play one minutes, emmm let us wait google drive...

@0ui0
Copy link
Author

0ui0 commented Feb 14, 2023

I can see the video, I'll watch it later today.

here is the google drive:link

@JesseKoldewijn
Copy link

Hey man, were you able to fix the issue at hand? @0ui0

@JesseKoldewijn
Copy link

JesseKoldewijn commented Feb 24, 2023

Also something completely besides the point. Is there any specific reason for client-side rendering your fairly complex looking data intensive platform that you're building right now? Reason for asking is because of the slow load-times and I can imagine that this matter would improve a lot when server-rendering the UI and only loading the actual content on the client side from js.

Apart from that bit. The side you're building looks great, props to ya man! (even though I can't read any of it without google translate)

@0ui0
Copy link
Author

0ui0 commented Mar 4, 2023

Also something completely besides the point. Is there any specific reason for client-side rendering your fairly complex looking data intensive platform that you're building right now? Reason for asking is because of the slow load-times and I can imagine that this matter would improve a lot when server-rendering the UI and only loading the actual content on the client side from js.

Apart from that bit. The side you're building looks great, props to ya man! (even though I can't read any of it without google translate)

Yeah, thanks for your advice and appreciation

now I only replace the @ sign as the video doing
I doubt the part <a href=abc@abc.com....> no quote sign?
or other reason let the page happen strange things
my markd.js is old version, I don't know whether or not update it will solve the problem. But when i update, the latest version seems incompatible with vite. So I keep the present version.

Maybe I will spend more special time pay attention to this.
But now, unless it happen chrome or firefox.
I care about other things emmmm

--- about client-side rendering ---
Because I hope it work on mobile application via webview as little migration work as possible and infact due to SEO, I prepare a simple server-side rendering version here URL. But when loading completely, the single page app will bring us better user experience then the traditional web page, and I organize mithril.js to building will be more easily and need not consider more situation. Tough the size of main.js certainly become more and more huge😂, and need more loading time. Maybe I will consider prepare a little easy game or other interaction way to help user spend the boring loading time...

--- about language ---
Because the original idea was to want it to run at my country locally and without thinking about internationalization😂, so....

@0ui0
Copy link
Author

0ui0 commented Oct 25, 2023

I can see the video, I'll watch it later today.

hey, i find this will lead to same problem today, also at ios safari:
m.trust(<a href=mailto:${htmlEncode("abc@abc.com")}>${htmlEncode("abc@abc.com")})
and I copy the output of console.log(...these string...) and as input to m.trust, as i before do, the problem missing

so strange

@dead-claudia
Copy link
Member

I can see the video, I'll watch it later today.

hey, i find this will lead to same problem today, also at ios safari:

m.trust(<a href=mailto:${htmlEncode("abc@abc.com")}>${htmlEncode("abc@abc.com")})

and I copy the output of console.log(...these string...) and as input to m.trust, as i before do, the problem missing

so strange

@0ui0

Just to verify: does this cause a crash?

`<a href=mailto:${htmlEncode("abc@abc.com")}>${htmlEncode("abc@abc.com")}</a>`

If not, does this?

var elem = document.createFragment("div")
elem.insertAdjacentHTML("afterbegin", `<a href=mailto:${htmlEncode("abc@abc.com")}>${htmlEncode("abc@abc.com")}</a>`)

If that doesn't either, does this?

var elem = document.createFragment("div")
elem.innerHTML = `<a href=mailto:${htmlEncode("abc@abc.com")}>${htmlEncode("abc@abc.com")}</a>`

@dead-claudia
Copy link
Member

Oh, and can you make a full code sample of something that crashes on https://flems.io, https://codepen.io, or similar?

I'm typing this from an iPhone, so I definitely have a device to test it on. 🙂

@dead-claudia
Copy link
Member

@JesseKoldewijn
Copy link

I don't see a triggered click on safari (iOS 17.1) either.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Question For issues that are purely questions about Mithril, not necessarily bug reports or suggestions
Projects
None yet
Development

No branches or pull requests

4 participants