Coding Diary

Should not use esc_html() when printing shortcode

Late last night, I received a message from my friend.

Hey, I have a problem which I can’t solve it. I copy contact form 7 shortcode from the backend and show it on frontend, but it shows [contact-form-7 404 "Not found"]

He gave me the credential to access. I made some checkings:

echo do_shortcode( get_theme_mod( 'step_form' ) );
// The result is [contact-form-7 404 "Not found"], this is his problem.

print_r( get_theme_mod( 'step_form' ) );
// The result is [contact-form-7 id="66" title="Contact form 1"], same as the shortcode I used.

echo do_shortcode( '[contact-form-7 id="66" title="Contact form 1"]' );
// I use the shortcode directly and it works.

print_r( '[contact-form-7 id="66" title="Contact form 1"]' == get_theme_mod( 'step_form' ) );
// The result is false. Oh, they are different.

I use print_r() to print two strings in two lines to compare, and this is the result:

Look like no different. But I noticed to the quote characters.

$form_1 = get_theme_mod( 'step_form' );
$form_2 = '[contact-form-7 id="66" title="Contact form 1"]';

print_r( $form_1[19] === $form_2[19] );
// 19 is the index of quote character, and the result is false.

Oh. I think I found the problem. They are two different characters: straight double quote and open double quote (read more here: http://practicaltypography.com/straight-and-curly-quotes.html)

My friend declared sanitize_callback for that setting is esc_html. It means that shortcode is passed through esc_html() function before saving, this converts the straight double quote to open or close double quote.

If you use var_dump() instead of print_r() to check and Xdebug is enabled, you can easily see the different, it will save a lot of time for you.

var_dump( get_theme_mod( 'step_form' ) );
// Result: '[contact-form-7 id="66" title="Contact form 1"]'

Conclusion:

Should not use esc_html() (or some equivalent functions) when printing shortcode. It will convert the straight quote to open or close quote, your shortcode can be broken.

One more advice. You should always escape late the output. But do not abuse it or do it wrong.

1 thought on “Should not use esc_html() when printing shortcode”

Leave a Reply

Your email address will not be published. Required fields are marked *