$attrbutes always has a space on when it calls Xss::attributes which leads to unnecessary calls to preg_match() and preg_replace().

Measurements

On the user permissions page with 11 roles:

Function Name Calls Diff Calls
Diff%
Incl. Wall
Diff
(microsec)
IWall
Diff%
Excl. Wall
Diff
(microsec)
EWall
Diff%
Incl.
MemUse
Diff
(bytes)
IMemUse
Diff%
Excl.
MemUse
Diff
(bytes)
EMemUse
Diff%
Incl.
PeakMemUse
Diff
(bytes)
IPeakMemUse
Diff%
Excl.
PeakMemUse
Diff
(bytes)
EPeakMemUse
Diff%
trim 751 51.9% -10 -0.0% -10 -0.0% 30,624 2036.2% 30,624 2036.2% 0 0.0% 0 0.0%
strlen -733 -50.6% -15 -0.0% -15 -0.0% -16 -1.1% -16 -1.1% 0 0.0% 0 0.0%
preg_match -733 -50.6% -695 -0.7% -695 -0.7% -256 -17.0% -256 -17.0% -1,640 -101.5% -1,640 -101.5%
preg_replace -733 -50.6% -3,201 -3.4% -3,201 -3.4% -113,632 -7555.3% -113,632 -7555.3% -1,472 -91.1% -1,472 -91.1%
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

alexpott’s picture

Issue summary: View changes
Status: Active » Needs review
FileSize
605 bytes

Here's a patch.

catch’s picture

Status: Needs review » Needs work

The last submitted patch, 1: 2506349.1.patch, failed testing.

Status: Needs work » Needs review

alexpott queued 1: 2506349.1.patch for re-testing.

alexpott’s picture

The first test run failed because it got terminated on a long running bot.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

Replacing two regular expressions with a single trim doesn't sound like the worst of an idea :)

alexpott’s picture

Issue tags: +Needs backport to D7

This exists in D7 too.

Wim Leers’s picture

Wow, impressive find :)

xjm’s picture

So I made the mistake of trying to understand why this was necessary by reading Xss::split() and Xss::attributes(). Save yourself.

I did however find myself wondering why the regex doesn't just exclude the optional leading and/or trailing space from the match? @alexpott is checking this out.

alexpott’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
693 bytes

I thought we needed to worry about space on the front and on the end of the $attrlist variable in Xss::split(). I was wrong. The regexes in Xss::attributes() are greedy when it comes to end space. So we can lose the trim. Nice call @xjm

Test scenario: standard profile, user/permissions, and no additional roles added - so just the 3 that come with core.

Run #5584aa49c883e Run #5584aa212b74e Diff Diff%
Number of Function Calls 269,985 268,722 -1,263 -0.5%
Incl. Wall Time (microsec) 792,088 772,569 -19,519 -2.5%
Incl. MemUse (bytes) 43,498,912 43,499,080 168 0.0%
Incl. PeakMemUse (bytes) 47,720,640 47,720,480 -160 -0.0%

I don;t think wall time is indicative of anything.

Function Name Calls Diff Calls
Diff%
preg_replace -421 -33.3%
strlen -421 -33.3%
preg_match -421 -33.3%

Obviously there is the possibility the additionally whitespace matching in the regex is more costly than the trim() but that'd surprise me.

Wim Leers’s picture

Status: Needs review » Reviewed & tested by the community
catch’s picture

Issue tags: +needs profiling

Would be good to see the profiling comparison just to see that loop still gone.

alexpott’s picture

@catch that's in #10 - no calls to trim now and just less function calls.

  • catch committed 0dbb619 on 8.0.x
    Issue #2506349 by alexpott: Unnecessary looping in Xss::filter when...
catch’s picture

Status: Reviewed & tested by the community » Fixed

Sorry missed that somehow.

Committed/pushed to 8.0.x, thanks!

alexpott’s picture

Version: 8.0.x-dev » 7.x-dev
Status: Fixed » Patch (to be ported)

This additional loop happens in D7 too.

cilefen’s picture

Status: Patch (to be ported) » Needs review
FileSize
484 bytes

  • catch committed 0dbb619 on 8.1.x
    Issue #2506349 by alexpott: Unnecessary looping in Xss::filter when...

  • catch committed 0dbb619 on 8.3.x
    Issue #2506349 by alexpott: Unnecessary looping in Xss::filter when...

  • catch committed 0dbb619 on 8.3.x
    Issue #2506349 by alexpott: Unnecessary looping in Xss::filter when...

  • catch committed 0dbb619 on 8.4.x
    Issue #2506349 by alexpott: Unnecessary looping in Xss::filter when...

  • catch committed 0dbb619 on 8.4.x
    Issue #2506349 by alexpott: Unnecessary looping in Xss::filter when...
joseph.olstad’s picture

RTBC, I just checked D8, the same code has been there since it was committed two years ago and is still in 8.5.x, if it's good enough for D8, it's good enough for D7. Passes all tests. I cannot find any logical reason why this should not be committed. If D8 is production ready, then this patch should be ready for D7. So therefore saying this patch not ready for D7 means that D8 is not ready for production. I doubt that anyone is willing to say otherwise.

Patch #17 still applies albeit with offset, reroll same.

joseph.olstad’s picture

all green , kicked php 5.4 again, it passes, all currently supported versions pass tests. This is a win!

Pol’s picture

This is fine for me as well.

joseph.olstad’s picture

Version: 7.x-dev » 8.0.x-dev
Status: Reviewed & tested by the community » Fixed

This was fixed in 8.0.x

marking this as fixed

As per the backport policy, I created a new D7 issue , for the D7 backport of the same, see:
#3008166: [D7] Unnecessary looping in Xss::filter when processing attributes.

joseph.olstad’s picture

Issue tags: -Drupal 7.60 target, -Needs framework manager review

removed tags , they're present on the D7 backport issue

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.