Make WordPress Core

Opened 9 years ago

Last modified 6 years ago

#35591 reopened defect (bug)

Shortcode Attributes Parsing Issue

Reported by: markclotfelter's profile markclotfelter Owned by:
Milestone: Priority: normal
Severity: normal Version: 4.4.1
Component: Shortcodes Keywords: reporter-feedback
Focuses: Cc:

Description

I'm using the following custom shortcode: [expert_profile mode="desktop" expert="142"]

And when the attributes are parsed using the following method:
extract( shortcode_atts( array(

'mode' => 'desktop',
'expert' => '0',
'num_to_show' => '25',
'tooltip' => 'on'

), $atts ) );

the "expert" attribute/variable is getting quotes around the end result after being parsed

Attachments (1)

35591.php (932 bytes) - added by aaroncampbell 9 years ago.
MU plugin for testing

Download all attachments as: .zip

Change History (15)

#1 follow-up: @swissspidy
9 years ago

  • Keywords close added

Shortcode attributes are strings, no matter what you pass them. The parser can't know what you expect to be returned and expert="123"is no different than expert="abc".

In your example, $atts['expert'] would be '142' (a string). If you need an integer value, just use (int) or absint(). The same goes for boolean flags like foo="true" or bar="false". You should cast the types explicitly.

Ps. I wouldn't recommend using extract() as it makes debugging more difficult.

#2 in reply to: ↑ 1 ; follow-up: @markclotfelter
9 years ago

i understand the concept of what the parser is doing. i didn't expect it to give me an integer.
my point is that what it returned had quotes attached to it (wrapped around it) when i went to use that variable. (that's NOT fully successful parsing) The other variables i've used do NOT have quotes.
the initial quotes around anything being passed as attributes to a shortcode should get all outside quotes stripped from them... ALL OF THEM. And, it should be uniform.

Replying to swissspidy:

Shortcode attributes are strings, no matter what you pass them. The parser can't know what you expect to be returned and expert="123"is no different than expert="abc".

In your example, $atts['expert'] would be '142' (a string). If you need an integer value, just use (int) or absint(). The same goes for boolean flags like foo="true" or bar="false". You should cast the types explicitly.

Ps. I wouldn't recommend using extract() as it makes debugging more difficult.

#3 in reply to: ↑ 2 @markclotfelter
9 years ago

Just to clarify, what i meant by "ALL OF THEM" was in reference to stripping way the first layer of quotes for ALL VARIABLES. Stripping away the first layer is expected behavior; leaving them, is not.
(the results of an unbiased parser should be uniform)

Replying to markclotfelter:

i understand the concept of what the parser is doing. i didn't expect it to give me an integer.
my point is that what it returned had quotes attached to it (wrapped around it) when i went to use that variable. (that's NOT fully successful parsing) The other variables i've used do NOT have quotes.
the initial quotes around anything being passed as attributes to a shortcode should get all outside quotes stripped from them... ALL OF THEM. And, it should be uniform.

Replying to swissspidy:

Shortcode attributes are strings, no matter what you pass them. The parser can't know what you expect to be returned and expert="123"is no different than expert="abc".

In your example, $atts['expert'] would be '142' (a string). If you need an integer value, just use (int) or absint(). The same goes for boolean flags like foo="true" or bar="false". You should cast the types explicitly.

Ps. I wouldn't recommend using extract() as it makes debugging more difficult.

#4 follow-up: @swissspidy
9 years ago

  • Keywords reporter-feedback added; close removed

@markclotfelter Can you share with us the result of var_dump( shortcode_atts( … ) )? I don't see any problem when registering & parsing this shortcode. Thanks.

#5 in reply to: ↑ 4 @markclotfelter
9 years ago

sure. i can definitely do that. (it may be a few hours before i have time... but, it'll happen ;-) )

Replying to swissspidy:

@markclotfelter Can you share with us the result of var_dump( shortcode_atts( … ) )? I don't see any problem when registering & parsing this shortcode. Thanks.

#6 @markclotfelter
9 years ago

var_dump( shortcode_atts( array(
		'mode' => 'desktop',
		'expert' => '0',
		'num_to_show' => '25',
		'tooltip' => 'on'
	), $atts ) );

PRINT OUTS...

array(4) { ["mode"]=> string(7) "desktop" ["expert"]=> string(3) "146" ["num_to_show"]=> string(2) "25" ["tooltip"]=> string(2) "on" }

Nothing looks wrong there to me... but, the strings that i get are different; as far as how well each one is stripped of quotes.

I'll send you printouts of each variable after extracting the variables.
(as i type this, it occurs to me that the problem might just be in the "extract" method)

This problem didn't appear until the update to 4.#

Last edited 9 years ago by SergeyBiryukov (previous) (diff)

@aaroncampbell
9 years ago

MU plugin for testing

#7 @aaroncampbell
9 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to worksforme
  • Status changed from new to closed

I added an mu-plugin for testing but I don't see any issues. The strings are coming through as expected (quotes stripped). If you are still having this issue, please add code to reproduce the issue when you re-open this.

#8 @TobiasBg
9 years ago

Another thing that could be causing this is that something is converting your regular quotation marks to typographically nice ones, before the Shortcode is parsed. Those would then appear inside the strings for each parameter value.
Therefore, please check if this happens with all other plugins deactivated and after switching to a WordPress default theme like Twenty Sixteen.

#9 @pcfreak30
9 years ago

  • Resolution worksforme deleted
  • Status changed from closed to reopened

Regarding what @TobiasBg said, I can confirm that there is an attribute parsing bug.

Put the following code in a plugin or theme:

add_shortcode('test', function($atts){
                return implode('',$atts);
        });

Then use this:

 [test a="b" c="d > 1000"]

Result:

 ”b””d>1000″

#10 @pcfreak30
9 years ago

It also appears if < is used, that it wont parse it at all.

#11 follow-up: @TobiasBg
9 years ago

The problem with the < is likely different, that's due to Shortcodes no longer allowing HTML, and for safety measures, the < is treated differently. See this blog post for some details.

The issue with those quotation marks might be the same as above, some extra wp_texturize() or similar. Can you therefore please check if this still happens after temporarily deactivating all other plugins and after switchting to a WordPress default theme like Twenty Sixteen?

#12 in reply to: ↑ 11 @pcfreak30
9 years ago

Replying to TobiasBg:

The problem with the < is likely different, that's due to Shortcodes no longer allowing HTML, and for safety measures, the < is treated differently. See this blog post for some details.

The issue with those quotation marks might be the same as above, some extra wp_texturize() or similar. Can you therefore please check if this still happens after temporarily deactivating all other plugins and after switchting to a WordPress default theme like Twenty Sixteen?

Sorry, I should have mentioned that. Yes I disabled everything. This is a stock/vanilla install.

#13 @TobiasBg
9 years ago

Thanks for checking. I can confirm this now, as soon as there's an > in an attribute value, all values get extra quotation marks, which are then also texturized.

#14 @SergeyBiryukov
9 years ago

  • Milestone set to Awaiting Review
Note: See TracTickets for help on using tickets.