When I run TruncateHTML on an HTML fragment that has > 256 children, I get an error "Maximum function nesting level reached" on TruncateHTML::removeProceedingNodes(). The reason is that removeProceedingNodes() goes one level of recursion deeper for every next sibling (not child, sibling!) under a parent element. Usually this is not a problem but if you have elements with many children, the call stack grows too large.
I will attach a patch that appears to solve this issue.
In order to replicate this, XDebug has to be enabled and the configuration should include the xdebug.max_nesting_level setting.
| Comment | File | Size | Author |
|---|---|---|---|
| #20 | smart_trim_applied_patch.png | 69.36 KB | ankondrat4 |
| #14 | max_function_nesting-3013628-13.patch | 1.6 KB | pcate |
| #12 | max_function_nesting-3013628-12.patch | 1.49 KB | ultimike |
| #7 | maximum_function_nesting-3013628-D8-7.patch | 1.2 KB | dimilias |
| #7 | test_only.patch | 491 bytes | dimilias |
Issue fork smart_trim-3013628
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
sbesselsen commentedHere's my patch:
Comment #3
pcate commentedPatch fixed the issue for me.
Comment #4
pcate commentedComment #5
markie commentedCan I get a use case or sample HTML for testing?
Comment #6
markie commentedStill looking for a use case to test locally.
Comment #7
dimilias commentedI ran across this today. Indeed the patch solves the case for me.
I provided a test that proves the failure.
I see that locally though, for some reason the rest of the test cases fail as well though they work on the website. Let's see how it will behave here.
Comment #8
dimilias commentedCould we have a test suite run here?
Comment #9
pfrenssenSetting this to minor since this is more of an environment configuration problem which is unlikely to happen in production environments. In order to replicate this the following conditions need to be met:
xdebug.max_nesting_leveloption must be set.Still this is worthwhile to fix to make sure the module works also in development environments with XDebug enabled, and also to reduce the memory footprint in production environments.
The patch looks good to me. I tried to run the tests locally, but as expected this can only be reproduced with XDebug enabled and configured to limit recursion. As mentioned by @idimopoulos above the current test suite is failing, but fixing this is out of scope of this issue, it is being handled in #3143589: Tests are failing.
Here is the result with only the test applied:
Here is the output with only the test and XDebug enabled and set to a recursion level of 32:
And here with patch + test:
So the test correctly detects that the issue is fixed, even though it is only reproducible using XDebug.
Fixing the other tests is out of scope, so this is RTBC.
Comment #10
pfrenssenComment #11
pfrenssenUpdating issue summary to clarify that this can only be replicated using XDebug.
Comment #12
ultimikeI've re-rolled this against the 2.0.x branch with a couple of changes:
1. With the existing unit tests fixed #3222068: Unit tests failing, I've added an additional (very similar) test for this for truncating by words (as well as characters).
2. I'm pretty sure the loop in
removeProceedingNodes()needs to be inside the existingif ($nextnode !== NULL) {- if not, the existing (now fixed) tests fail.-mike
Comment #13
pcate commentedThe patch doesn't apply for me with the stable 2.0.0 version of the module.
Comment #14
pcate commentedUpdated patch attached for stable 2.0.0 version. It is based on #12.
Comment #15
ultimikeLet's convert this to an issue fork against 2.1.x and see how it goes. Seems like a reasonable change (and it has an associated test!)
-mike
Comment #17
ultimikeI converted the patch into an MR (tests passing) - I also tweaked the test data a little.
Needs a review or two.
-mike
Comment #18
markie commentedMR makes sense but are there testing instructions for it? Does the pipeline check xdebug? What limits the test to just 3 instances of the test string?
Not enough to say "needs work" but am curious..
Comment #19
ultimikeMy understanding of this issue is if there are bucketloads of HTML elements in the field that Smart Trim is operating on, when using xdebug, the
xdebug.max_nesting_levellimit can be hit.For manual testing, you'd need data to be Smart Trimmed that contains a bunch of HTML - so much that the
xdebug.max_nesting_levelit hit (as well as xdebug enabled, obviously).The Gitlab pipeline does not run with xdebug enabled as far as I know.
-mike
Comment #20
ankondrat4 commentedHello.
MR was applied as expected. +1 RTBC.
Comment #22
markie commentedMerging this in. Thanks