Make WordPress Core

Opened 2 years ago

Last modified 5 weeks ago

#57790 reopened defect (bug)

Parsing of Shortcode Attributes: bug locating a final attribute

Reported by: lemernbag's profile lemernbag Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 6.1.1
Component: Shortcodes Keywords: changes-requested 2nd-opinion has-patch
Focuses: Cc:

Description

shortcode_parse_atts() uses the get_shortcode_atts_regex() pattern to return all attribute="value" matches, however the pattern does not account for shortcode strings where the final attribute pair does not have a space between " and ]


shortcode_parse_atts('[shortcode-name category="banana-stand" money="yes"]'); //no space

returns

Array(
    [0] => [shortcode-name
    [category] => banana-stand
    [1] => money="yes"]
)


whereas

shortcode_parse_atts('[shortcode-name category="banana-stand" money="yes" ]'); //has space

returns

Array(
    [0] => [shortcode-name
    [category] => banana-stand
    [money] => yes
    [1] => ]
)

I ran the get_shortcode_atts_regex() pattern through a couple regex testers and verified that the issue is the non-capturing group conditional following the end-quote of a value.

Change History (3)

#1 @alimuzzamanalim
2 years ago

  • Keywords 2nd-opinion added
  • Resolution set to invalid
  • Status changed from assigned to closed

Check the do_shortcode function.

It uses the get_shortcode_regex function to separate the shortcode name and attributes.
Then only passes the attributes to the shortcode_parse_atts function.

So I don't see any reason to treat it as a bug.

#2 @alimuzzamanalim
2 years ago

  • Resolution invalid deleted
  • Status changed from closed to reopened

This ticket was mentioned in PR #8533 on WordPress/wordpress-develop by @sahilgidwani.


5 weeks ago
#3

  • Keywords has-patch added; needs-patch removed

Trac Ticket: https://core.trac.wordpress.org/ticket/57790

### Fix: Correct Parsing of Final Shortcode Attribute Without Trailing Space

#### Issue Summary
The shortcode_parse_atts() function, which uses get_shortcode_atts_regex(), fails to correctly parse the last attribute of a shortcode when there is no space between the final attribute’s closing quote and the closing bracket ].

#### Steps to Reproduce

##### Current Behavior (Bug)

shortcode_parse_atts('[shortcode-name category="banana-stand" money="yes"]'); // No space

Output:

Array(
    [0] => [shortcode-name
    [category] => banana-stand
    [1] => money="yes"]
)

The last attribute (money="yes") is incorrectly treated as a separate entry instead of being parsed as a key-value pair.

##### Expected Behavior
When a space is included before the closing ], the function behaves correctly:

shortcode_parse_atts('[shortcode-name category="banana-stand" money="yes" ]'); // Has space

Output:

Array(
    [0] => [shortcode-name
    [category] => banana-stand
    [money] => yes
    [1] => ]
)

#### Root Cause
The issue stems from the get_shortcode_atts_regex() pattern, where the final attribute pair is not properly matched if there is no space before ]. The previous regex enforced a space (\s) or end-of-string ($) after an attribute, causing the last attribute to be misinterpreted.

#### Proposed Fix
The updated regex removes unnecessary lookaheads and ensures correct parsing regardless of whether a space exists before ].

##### Old Code:

return '/([\w-]+)\s*=\s*"([^"]*)"(?:\s|$)|([\w-]+)\s*=\s*\'([^\']*)\'(?:\s|$)|([\w-]+)\s*=\s*([^\s\'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|\'([^\']*)\'(?:\s|$)|(\S+)(?:\s|$)/';

##### New Code:

return '/([\w-]+)\s*=\s*"([^"]*)"|([\w-]+)\s*=\s*\'([^\']*)\'|([\w-]+)\s*=\s*([^\s\'"\]]+)|"([^"]*)"|\'([^\']*)\'|(\S+)/';

#### Test Results
After applying the fix, both cases now produce the expected output:

Array(
    [0] => [shortcode-name
    [category] => banana-stand
    [money] => yes
    [1] => ]
)

Ensuring that the last attribute is parsed correctly, regardless of spacing.

#### Impact & Compatibility

  • This fix improves accuracy without affecting existing correctly formatted shortcodes.
  • Fully backward-compatible with previous WordPress versions.
  • Ensures shortcode_parse_atts() is more robust when handling shortcode attributes.
Note: See TracTickets for help on using tickets.