Skip to content

[Serializer] make XmlEncoder stateless thus reentrant #38534

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

Merged

Conversation

connorhu
Copy link
Contributor

Q A
Branch? 5.x
Bug fix? yes
New feature? no
Deprecations? no
Tickets Fix #37354
License MIT

Changing dom property of XmlEncoder to stackable. It fixes a DOMException "Wrong document error". When you calling XmlEncoder->encode() in parallel createDomDocument replaces the DomDocument object.
Test code:
https://github.com/connorhu/symfony-serializer/blob/master/test.php

@connorhu connorhu requested a review from dunglas as a code owner October 12, 2020 20:24
@connorhu connorhu force-pushed the serializer/stackable-xml-encoder branch from 6b27d66 to 39615f4 Compare October 12, 2020 20:30
@connorhu connorhu changed the title changed dom property to pop/pushable [serializer ]changed dom property to pop/pushable Oct 12, 2020
@connorhu connorhu changed the title [serializer ]changed dom property to pop/pushable [serializer] changed dom property to pop/pushable Oct 12, 2020
Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you please add a test case and rebase+target the lowest branch where this issue exists (3.4 I suppose?)

@nicolas-grekas nicolas-grekas added this to the 3.4 milestone Oct 13, 2020
@stof
Copy link
Member

stof commented Oct 13, 2020

Rather than maintaining a stack of current document (which is not properly maintained in case of errors btw, as the unstacking should be done in a finally block), a better solution could be to avoid the need for the state at all, by removing $this->dom. Instead, the \DOMDocument could be passed as argument to private methods needing it (and a bunch of the existing private methods might use $node->ownerDocument instead of $this->dom to avoid the need to add an argument in their signature).

@connorhu
Copy link
Contributor Author

@stof I have tested the ownerDocument method. It seems to be a working solution and the tests are running but. At the appendNode method the $parentNode argument can be DomDocument so the onwerDocument is null:
connorhu@a6f0be3#diff-b031dbb2186367839adfe20696612866da91513dd315f00ad6df23b5d38fca74L467-R452

@stof
Copy link
Member

stof commented Oct 13, 2020

@connorhu if the parentNode is already a DomDocument, you already have the DomDocument. That's fine to me.

@connorhu connorhu force-pushed the serializer/stackable-xml-encoder branch from 39615f4 to 06ac911 Compare October 13, 2020 13:39
@stof
Copy link
Member

stof commented Oct 13, 2020

If we want to make the encoder re-entrant, I think the state in $this->context is also an issue, not only $this->dom

@connorhu connorhu force-pushed the serializer/stackable-xml-encoder branch from 06ac911 to a8c344f Compare October 13, 2020 14:10
@nicolas-grekas nicolas-grekas changed the base branch from 5.x to 3.4 October 14, 2020 16:34
@nicolas-grekas nicolas-grekas changed the title [serializer] changed dom property to pop/pushable [Serializer] removed dom property from XmlEncoder Oct 14, 2020
@nicolas-grekas nicolas-grekas force-pushed the serializer/stackable-xml-encoder branch 2 times, most recently from b58889b to 85a02f5 Compare October 14, 2020 16:37
@nicolas-grekas
Copy link
Member

I rebased the PR for branch 3.4 but there are some failure to fix, could you please have a look?

@connorhu
Copy link
Contributor Author

@nicolas-grekas Of course! Thank you!

@connorhu connorhu force-pushed the serializer/stackable-xml-encoder branch from 89852c4 to db628e6 Compare October 14, 2020 19:27
@connorhu
Copy link
Contributor Author

I think my original bug is now fixed. The current version of XmlEncoder in symfony 3.4 is not so complex. I don't see how can cause the context property a bug like the dom did.

@stof
Copy link
Member

stof commented Oct 15, 2020

@connorhu the issue is exactly the same that with $this->dom actually: if you call the serializer again during serialization, sotring the call-specific state in the instance will break as the encoder won't be re-entrant (it handles only one state at a time), and it might end up using the wrong state.
The reason you don't see an issue in your reproducing code is because you use an empty context for both calls, so using the wrong empty context is not an issue.

@connorhu
Copy link
Contributor Author

@stof I see the possibility of the context bug, but If you use nothing from context after initialization it can't cause a bug. Safer to remove context property instead of making a note for the future code changes.

@stof
Copy link
Member

stof commented Oct 15, 2020

@connorhu the thing is, the XmlEncoder is using the context in some of the private methods.

@connorhu
Copy link
Contributor Author

@stof Should I merge the context property remove patch into in this PR? The referred bug only describes the bug about the dom property.

@fabpot fabpot modified the milestones: 3.4, 4.4 Oct 28, 2020
@nicolas-grekas nicolas-grekas changed the title [Serializer] removed dom property from XmlEncoder [Serializer] make XmlEncoder stateless thus reentrant Jan 28, 2022
@nicolas-grekas nicolas-grekas changed the base branch from 3.4 to 4.4 January 28, 2022 10:10
@nicolas-grekas nicolas-grekas force-pushed the serializer/stackable-xml-encoder branch from db628e6 to 693f9ab Compare January 28, 2022 10:10
Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I rebased and implemented the remaining)

@nicolas-grekas
Copy link
Member

Thank you @connorhu.

@nicolas-grekas nicolas-grekas merged commit 5c67f40 into symfony:4.4 Jan 31, 2022
This was referenced Feb 28, 2022
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.

[Serializer] paralell XMLEncoder::encode can cause "Wrong Document Error"
6 participants