Problem/Motivation
See #2807705: FormattableMarkup::placeholderFormat() can result in unsafe replacements. We've supported placeholders that don't start with @, !, % or : forever (! was removed in Drupal 8). We no longer support them.
In Drupal 8 we trigger 2 different errors.
- If the placeholder starts with a non alphanumeric error then we trigger a E_USER_ERROR.
- If the placeholder start with an alphanumeric character AND is in contained in the string then we trigger a E_USER_DEPRECATED.
Proposed resolution
- Trigger a silenced E_USER_DEPRECATION if the placeholder is not in the string and starts with an alphanumeric character. This situation was not accounted for in Drupal 8 so we need to follow our deprecation policy.
- For all other occurrences of non standard placeholders trigger a E_USER_WARNING on all non standard placeholders passed to \Drupal\Component\Render\FormattableMarkup::placeholderFormat(). E_USER_WARNING is chosen because we do not do the replacement and therefore there are no risks in continuing on. This is slightly less strict than the current behaviour of issuing an E_USER_ERROR but this is a better experience for real sites. The error will be logged but the site will continue to work. This is unlikely to be a critical error.
Remaining tasks
User interface changes
None
API changes
None - non standard placeholders have not been supported since 8.2.0 - #2807705: FormattableMarkup::placeholderFormat() can result in unsafe replacements
Data model changes
None
Comment | File | Size | Author |
---|---|---|---|
#30 | 23-29-interdiff.txt | 2.31 KB | alexpott |
#29 | 2807743-9.1.x-29.patch | 7.44 KB | alexpott |
#29 | 23-29-interdiff.txt | 7.44 KB | alexpott |
#23 | 2807743-9.1.x-23.patch | 7.41 KB | alexpott |
#15 | 2807743-15.patch | 8.05 KB | alexpott |
Comments
Comment #2
alexpottComment #3
catchJust re-titling, since we don't support these as such already.
Comment #4
catchShould probably be an assert (+ no-op) rather than an exception?
Comment #5
katbat CreditAttribution: katbat commentedComment #6
apadernoComment #8
alexpottI think we can be a bit more lenient here are trigger a helpful warning. We've not being doing the replacement since at least 8.3.0 so people have had time to fix their placeholders but there's no reason to error out here - we'll leave the string alone and the warning will be useful.
Comment #10
alexpottHmmm I think we might be only able to handle this we a proper deprecation as there is a case we didn't error for.
Comment #12
alexpottComment #13
alexpottComment #15
alexpottFixing the remaining errors.
Comment #16
alexpottThis is fun one. The new deprecation is catching an incorrect setting of context!
I have been wondering if we should just silently ignore such placeholders. This convinces me we should check the validity of them as it helps find things like this.
I think we might want to split this fix out into a separate issue so it can be fixed in 8.9.x too.
Comment #17
andypostComment #18
alexpottI've created #3109795: Entity plural label context is not set as expected to address the bug found here.
Comment #19
catchI agree with deprecating this for Drupal 10, but reckon we could still deprecate it in 8.9 - it's deprecating a code path, not deprecating actual code, and code doing this is already buggy.
Comment #20
apadernoThere is a small typo in the following comment (suuport instead of support).
Comment #21
andypostShould it postponed on bug fix? #3109795: Entity plural label context is not set as expected
Comment #22
xjmThis is disruptive, so it would be at least a minor-only change. Since 8.9.x and 9.0.x are now in beta, I'm moving this to 9.1.x. Thanks!
I wonder if there's a way to do this less disruptively with a deprecation for the minor?
Comment #23
alexpottRerolled now the blocker landed and fixed #20.
Comment #24
neclimdulThat's sort of what the patch does. The patch can be hard to read in places but summarizing the test changes we can see the actual effect of the change.
So this patch is doing 3 things but only 2 should matter.
1) Removing a deprecation. Seems like this should have been in 9.0 but it didn't have a timeline or standard deprecation testing. Probably because of its age.
2) Deprecating a previously unhandled error condition showing mistakes was silently thrown away previously. This is a DX improvement as seen in #16 but maybe isn't allowed in 9.0.
If we really wanted to target 9.0 we could just split the new deprecation and replace it with a TODO or just backport this without the deprecation. A follow up at this point would be one line and a test but I'm not sure it is worth it since we are so late in the 9.0.
Comment #26
alexpottI think #23 just failed due to a random JS test fail.
Comment #27
catchI feel like I'm missing something, but:
1. Where is
$error['%severity_level']
used?2. Aren't we now passing $error['%severity_level'] and $error['severity_level'] to the ->log() call?
Comment #28
neclimdulyeah good catch... catch. I think without looking too close it just made sense to keep it. I dug through this for a while and error is 99% a local variable and its not used locally and when we hand it off we add the variable back so in the bigger picture as shown in 2) setting '%severity_level' doesn't seem needed. If a logger wants to add the log severity to the message for some reason it has all it needs to make that happen.
Looking at the diff in #27.1 in a different context, I don't think we actually pass this to
t()
, it looks like its all strtr and FormatableMarkup right? We can just say "... as it is not a valid replacement."Comment #29
alexpottYeah I added %severity_level for a sort of BC. But I agree that it is not required.
However I disagree about the
\Drupal::logger('php')->log($severity, '%type: @message in %function (line %line of %file) @backtrace_string.', $error + ['backtrace' => $backtrace, 'severity_level' => $severity]);
- yes contrib implementations could be like\Drupal\syslog\Logger\SysLog::log()
and use the $level provided but they could also use$context['severity_level']
and we should not break that here.Comment #30
alexpottHere's the correct interdiff.
Comment #31
catch#29 looks better.
Comment #33
catchCommitted e85462d and pushed to 9.1.x. Thanks!
I think it's fine for this to just land in 9.1.x and not be backported.
Comment #36
quietone CreditAttribution: quietone at PreviousNext commentedClosed #2860659: Broken argument replacements should trigger an E_USER_ERROR, not E_USER_DEPRECATED as a duplicate, adding credit.
Comment #37
TR CreditAttribution: TR commentedThis is still causing problems. Please see #3173103: False positives when identifying what is a placeholder, for deprecation error. In short, the PSR-3
$context
parameter holds more than just placeholders, but Drupal generates a warning if the array keys in$context
don't conform to the "placeholder" requirements.