Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Since PHP 7 the preg engine uses a just in time compiler. This one can cause strange issues:
https://bugs.php.net/bug.php?id=70110
When a YAML file contains a value that consists of a lot of newlines, we're affected.
We've been affected by the PHP bug until Drupal 8.4, where the symfony components have been updated to a newer version in #2712647: Update Symfony components to ~3.2. As we want to ensure we'll not encounter the same problem again this issue is only about adding the test that used to fail in Drupal 8.3.x. The problem itself has been fixed in Symfony.
Comment | File | Size | Author |
---|---|---|---|
#38 | 2792877-34-test-only.patch | 994 bytes | Anonymous (not verified) |
#34 | 2792877-34.patch | 2.59 KB | jofitz |
#9 | 2792877_php7_jit_yaml_parser_workaround.patch | 2.51 KB | mkalkbrenner |
#5 | 2792877_yaml_newlines_php7_failing_test_combined_with_2792831.patch | 1.16 KB | mkalkbrenner |
Comments
Comment #2
mkalkbrennerComment #3
mkalkbrennerYamlSymfonyTest is not executed on testbot?
https://dispatcher.drupalci.org/job/default/204546/testReport/Serializat...
Comment #4
mkalkbrennerOK, the test is skipped because of #2792831: YamlSymfonyTest must not require PHP yaml extension :-(
Comment #5
mkalkbrennerHere's a combined patch which should now fail on PHP 7.
Comment #6
mkalkbrennerComment #7
mkalkbrennerHooray, the expected fail on PHP 7 when the amount of newlines gets too much.
Comment #8
mkalkbrennerNow the fix including the patch from #2792831: YamlSymfonyTest must not require PHP yaml extension to get the test to run at all.
Comment #9
mkalkbrennerre-roll because #2792877: Symfony YAML parser fails on some strings when running PHP 7 got committed.
Comment #10
neclimdulcan't say I'm excited about turning of jit. is there any related upstream symfony discussion?
Comment #11
mkalkbrennerI considered creating a pull request for symfony as well. But I found that one which seems to be a better solution: https://github.com/symfony/symfony/pull/19750
Nevertheless the search_api_solr_multilingual requires a solution. We have language and domain specific word lists which break the jit limit. These lists are coming from libre office. Not using configuration management for that will be a major drawback.
Comment #12
neclimdulI don't know how you're configuring things but it seems like it might work better for you to store them as a yaml sequence(array) instead. you should get native datastructures saving you a step of exploding the list on \n and should avoid this problem.
Comment #13
mkalkbrennerThat should be discussed in the Search API Solr Multilingual issue queue. But we had that discussion already and selected the string with newlines for good reasons, for example copy and paste stuff from libre office or Solr configs.
BTW we don't have trouble with the initial import as we use the literal style, indicated by the pipe "|".
Comment #14
mkalkbrennerComment #15
cspitzlay... which does not seem to be supported by the Symfony YAML dumper. Which is sad as it would not only circumvent the jit stack limit issue (#2792843: Drupal crashes after exporting and re-importing Solr field configs) but also be more readable in our use case (noun lists in language-specific Solr field configuration).
Comment #16
neclimdulUI shouldn't dictate storage
Comment #17
cspitzlayWhat UI are you talking about? I was talking about the file on disk when viewed in a text editor or when diffed by a VCS system after a roundtrip through Dupal (config import and then config export).
The files for newly added languages are typically compiled manually from external sources that are plain text.
Currently there isn't even a GUI to edit them in the D8 version of search_api_solr_multilingual.
But I agree with mkalkbrenner that a discussion, if any, should better take place in Search API Solr Multilingual.
The point of this issue here is that valid Yaml cannot be parsed.
Comment #18
neclimdulI'm not trying to discount your problem only trying to help offer workarounds since this is a pretty far edge case of the YAML parser. I'm also interested in getting it fixed which is why I tagged it a contrib blocker to get more eyes on it. I'm sorry.
Comment #19
cspitzlayDon't be. Thanks for your effort.
I just wanted to give some background why the original files
contain large lists of newline-separated data
(which the Yaml parser can read just fine).
Comment #20
andypostComment #21
andypostComment #22
andypostComment #23
alexpottThe problem here is that
pcre.jit
has been implemented to improve regular expression performance and Symfony's yaml parser makes heavy use of regular expressions.Comment #24
tstoecklerMaybe we can disable JIT only conditionally? I'm not sure if there's a reliable way to check for this error, but looking at https://bugs.php.net/bug.php?id=70110 it seems that it only affects long strings. Maybe we can do something like
strlen($string) > 1000
so we can still get the performance benefit for most files?Comment #25
hchonov@tstoeckler this would not work as with JIT you might first encounter a string which length is under 1000 characters but later after the pattern is compiled you might encounter a bigger string. And also it is not only the length of the string that matters but also how complicated it is, which means it might pass with a string which length is above 1000 characters but fail with a string which length is under 1000 characters.
Comment #26
mkalkbrennerMaybe that's a good approach. But as demonstrated in the tests we should not use the length of a string but the amount of newlines:
Comment #27
mkalkbrennerOK, there're also other issues with "complicated" long strings. So maybe a simple strlen() is a good trade-off.
Comment #28
mkalkbrenner@cspitzlay just reminded me that we can't have such a condition at all.
If the YAML parser passes some short strings using the jit compiler, the pattern is already "cached". Once it is cached turning of jit for long strings has no effect anymore.
Comment #29
tstoecklerSo I guess this also means that theoretically someone could use
preg_match()
with the same pattern that Symfony'sYaml
so that it will be compiled already and then even your patch would not work. I guess that's pretty far-fetched but still worth considering IMO.I thought whether instead of the current patch - or perhaps in addition to it - we could add a
hook_requirements()
warning about this. We could check if people are using the Symfony implementation and if so check if they havepecl.jit
on. And if so, recommend either turning it off or installing PECL YAML.Regarding the perfomance impact of turning off JIT: Since we now actually support using PECL YAML for decoding, perhaps it's acceptable do slightly slow down Symfony's YAML decoding as people who are performance conscious will use the PECL implementation anyway? Tentatively tagging "Needs benchmarks" as I think it would be good to know what kind of performance tradeoffs we are talking about here.
Comment #30
cilefen CreditAttribution: cilefen commentedI think this is related(?)...
Comment #33
jhedstromPatch no longer applying, and the IS could use updating to describe what's left to be done here.
Comment #34
jofitz CreditAttribution: jofitz at ComputerMinds commentedRe-rolled.
Comment #36
Anonymous (not verified) CreditAttribution: Anonymous commentedCann't reproduce this bug anymore. Perhaps after https://github.com/symfony/symfony/pull/19750.
Comment #37
hchonov@vaplas, the referenced GitHub pull request has been closed without merging it.
Comment #38
Anonymous (not verified) CreditAttribution: Anonymous commented@hchonov, thanks for correction, indeed. But test passes without fix now.
Comment #39
hchonovThe test that used to fail on 8.3.x indeed doesn't fail anymore on 8.4.x and later. It is not because of a PHP bug fix either as we see it passes on all the current versions - 7, 7.1 and 7.2.
The symfony components have been updated in 8.4.x to a newer version in #2712647: Update Symfony components to ~3.2, so most probably this is the reason for the test passing now.
Let's still get in the the test from #38, as the PHP bug will not be fixed soon. RTBCing it for that.
@vaplas++
Comment #40
hchonovOh and this is not major anymore.
Comment #41
mkalkbrennerI did a quick test and can confirm that exported Solr Field Type configs can be re-imported now.
Comment #42
alexpottHow about filing a PR to add this to Symfony's Yaml test suite? I'm not sure we should be added tests in our code for bugs in our dependencies.
Comment #43
neclimdulThat is a good point. Technically we're testing our wrapper but since its not testing any code we've actually implemented it does feel like something for their test suite.
Comment #44
alexpottActually they already added a test - see https://github.com/symfony/symfony/commit/f0256f1aa5285bef9e9c73d1afe85c... and https://github.com/symfony/symfony/pull/22067
Comment #45
hchonov@alexpott++, thank you for the findings.