Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upinnerHTML on a script tag escapes tag characters #14975
Comments
|
The cause is this match which says that the contents of script tags should be escaped. |
|
That code matches what is written at https://html.spec.whatwg.org/multipage/syntax.html#serialising-html-fragments for "If current node is a Text node". Interestingly, outerHTML works fine, and innerHTML does not. |
|
The |
|
Please make a comment here if you intend to work on this issue. Thank you! |
|
To fix this, in the case where the serializer is created with ChildrenOnly we should make the initial element contain the data for the actual element parent. We should add a unit test in html5ever for this case, as well as create a new WPT test for Servo. |
|
Actually, there's a useful |
|
Can I claim this? I have no experience with Servo (except testing) and little with Rust, so if it needs to be done quickly then I'm probably not the correct person... |
|
Please do! There's no rush, and the actual code changes will happen in the html5ever repository. |
|
To see how Servo uses the html5ever serializer, look at Element::GetInnerHTML and related code in the HTML parser serialize implementation. |
|
Hmm... This bug is tagged with "C - has test", but when I run "cargo test" all the tests pass. Is the test wrong? And the code says that the contents of a script tag should not be escaped (i.e. let script = false;), while this thread and the title says they are. What am I missing? |
|
The |
|
This comment explains the case in which the code does not operate correctly and chooses to escape the element contents when it should not. |
|
Have you encountered any problems with fixing the issue, @tormeh? |
|
No, well, I'm new to Servo and Rust and inexperienced in HTML, git and Github. So even though the bug itself is easy, everything around it really slows me down. Which is frustrating, which slows me down further, since the world has plenty of non-frustrating things to do. But I also learn quite a bit. |
|
#15148 ran into some problems due to the master of html5ever being different from the version that Servo was using. This is now available for anybody to work on again. |
|
Hi there! I would like to work on this bug. I'm new to bugzilla/servo and may need some additional help. I've looked into the code and wants to confirm if the main problem was caused by the return value for innerHTML from parent. Thanks! |
|
Also, is the value of the node equal to |
|
That is correct. |
|
I've read thru past comments from the previous developer but not sure where to begin with. Also, the problem was fixed and started to occur again due to the inconsistency in html5ever that were being used? Thank you for your help! |
|
No, the problem mentioned was in trying to use a local clone of html5ever in Servo, which is required in order to modify it and see the changes in Servo. |
|
First: add the test that demonstrates the problem. Second: get a local clone of html5ever working. Third: fix the problem in html5ever and make the test pass. |
|
Okay I'll add some testcases to my local servo clone just like @tormeh did. But I'm not sure how to interact the testcases in local servo clone with the local clone of html5ever you mentioned since they're two different repos? |
|
Sounds good! |
|
@moonlightdrive Did you make any progress here? |
|
Heyh @jdm, sorry for the late response (I've somehow muted the repo even though i didn't want to) Please consider me if the issue gets unassigned again ! |
|
I added the tests and have servo building with a local clone of html5ever. The problem I am facing now is finding where in html5ever I need to make the change. I thought the Additionally I am not clear on the difference between html5ever and xml5ever (or if that's even relevant to this issue) |
|
Hi @moonlightdrive I wrote Basically For example |
|
I linked to the appropriate serializer implementation in one of the earlier comments: https://github.com/servo/html5ever/blob/master/src/serialize/mod.rs |
|
Looks like this is also a cause of #16532 |
|
@moonlightdrive Are you still working on this? |
|
Hi, I am still working on it. Sorry I've been so slow. If this issue needs to be fixed soon I am happy to give it up and maybe take a look at another one. |
|
Still making progress @moonlightdrive? Do you have any questions that we can answer? |
|
I definitely have a question, or at least some confusion, but think I need to poke around a bit more to know exactly what it is. As far as I understand, the difference between the treatment of innerHTML and outerHTML is that the former is serialized with ChildrenOnly and the latter with IncludeNode. And this bug arises due to the fact that in the ChildrenOnly case, we didn't push that script node.. so when we check the parent to see if we need to escape, we've essentially discarded that information. As has already been said. But I don't see, in Another question: what is happening here? Is this where Not sure if I've been clear with my questions. Please let me know and I'll try to clarify. |
|
@moonlightdrive I think you're looking too deeply here. As to your second question, yes, through invoking |
|
Looking more carefully, I think I see why you're asking those questions. I think the right thing to do might be to modify the html5ever serialize method to push a meaningful stack entry if the traversal scope is |
|
@moonlightdrive Are you still working on this? |
|
I am actually a little unclear on where (which repository) to make this change. I have tried the following: I tried making the fix by changing the Also took a look at pushing to the stack in the Not sure if I've misunderstood how to implement this. Thank you |
|
Sorry for the delay in responding. Good investigation! You're right that html5ever cannot depend on Servo (especially since Servo depends on html5ever). The error about private types occurs because a public function would now have a private type in its public interface; the private type in this case is As for the optimal solution, I think I have a useful idea for you. Let's make the |
|
Yeah, that makes sense! I'll take a look at implementing that solution. Thanks :) |
|
I think what I actually need is a function that's part of the Serializer trait, which will push/pop elements to the stack, without doing any of the writes that I believe (and don't have a great grasp of Rust yet) that this function should have a signature like // i don't know what to name this fn yet
fn start_elem_without_write<T>(&mut self, elem: T);and that the implementation of this function for fn start_elem_without_write<ElemInfo>(&mut self, elem: ElemInfo) {
self.stack.push(elem);
}but this is evidently not right. The error I am getting is: expected struct 'serialize::ElemInfo', found type parameter. I guess this type parameter is |
Add functions for pushing/popping nodes without performing writes. This is necessary so that these nodes exist on the stack when we serialize the children nodes and may need the parent for context. Addresses servo/servo#14975
Add functions for pushing/popping nodes without performing writes. This is necessary so that these nodes exist on the stack when we serialize the children nodes and may need the parent for context. Addresses servo/servo#14975
change type ChildrenOnly to ChildrenOnly(Option<QualName>) This is necessary so that these nodes exist on the stack when we serialize the children nodes and may need the parent for context. Addresses servo/servo#14975 --- Opening this PR for feedback/review ~~This does work and solves the above bug. I'm not sure if this is the best implementation, as there's a bit of duplicated code. I thought about adding a boolean flag to `start_elem` that would determine whether the writes should be performed. But then I thought maybe when not writing, it's best not to call a function returning `io::Result<()>`?~~ Also not 100% sure if the xml implementation is the right thing to do Anyway, please let me know of any improvements/changes to make. Thanks :) <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/html5ever/277) <!-- Reviewable:end -->
Serializing childrenonly Rebased from #17896. --- - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #14975 (github issue number if applicable). - [x] There are tests for these changes <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/18747) <!-- Reviewable:end -->
Serializing childrenonly Rebased from #17896. --- - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #14975 (github issue number if applicable). - [x] There are tests for these changes <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/18747) <!-- Reviewable:end -->
Serializing childrenonly Rebased from #17896. --- - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #14975 (github issue number if applicable). - [x] There are tests for these changes <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/18747) <!-- Reviewable:end -->
Serializing childrenonly Rebased from #17896. --- - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #14975 (github issue number if applicable). - [x] There are tests for these changes <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/18747) <!-- Reviewable:end -->
In Firefox, this prints
<!-- hi -->. In Servo, it prints<-- hi -->.