custom-post-type-ui icon indicating copy to clipboard operation
custom-post-type-ui copied to clipboard

Post type label being encoded / double encoded...

Open rmorse opened this issue 2 years ago • 6 comments

Hey WebDevStudios! Long time user of your plugin :)

We develop another plugin, which lists post types, and we're having trouble with post types with special characters created by your plugin, which means when we output the labels, it looks like this (the second option is CPT UI post type)

image

What we've noticed:

  1. Create a post type with the label ' Special (notice the apostrophe at the beginning)
  2. Then fetch post types using the WP function get_post_types()
  3. Check the label, it will be: ' Special
  4. This is double encoded which seems like a bug... It should be ' Special
  5. Or even just ' Special

To verify WP behaviour, I tested registering a post type using the WP function register_post_type(), for example:

function wporg_custom_post_type() {
	register_post_type('wporg_product',
		array(
			'labels'      => array(
				'name'          => __("' Special", 'textdomain'),
				'singular_name' => __("' Special", 'textdomain'),
			),
			'public'      => true,
			'has_archive' => true,
		)
	);
}
add_action('init', 'wporg_custom_post_type');

And when we look at the label of this in a get_post_types() call, it looks like this: ' Special

To work around this we'd have to double entity_decode() post type labels generated by this plugin, which I don't think is a good idea (especially if someone purposely wanted some special chars to show, unlikely but possible).

Also I think whenever we see anything double encoded we've likely run into a bug.

Thanks

rmorse avatar Feb 05 '23 18:02 rmorse

Not sure what's going to be the best path forward here, since I would much rather have security cleanup measures in place than not.

Here's the code used when cleaning up a given label:

	foreach ( $data['cpt_labels'] as $key => $label ) {
		if ( empty( $label ) ) {
			unset( $data['cpt_labels'][ $key ] );
		}

		$label = str_replace( '"', '', htmlspecialchars_decode( $label ) );
		$label = htmlspecialchars( $label, ENT_QUOTES );
		$label = trim( $label );
		if ( 'parent' === $key ) {
			$data['cpt_labels']['parent_item_colon'] = stripslashes_deep( $label );
		} else {
			$data['cpt_labels'][ $key ] = stripslashes_deep( $label );
		}
	}

I have verified that the UI shows the apostrophe, and does save as the encoded version in the database. Not sure where the & portion is coming from, as I've checked and the label is still ' Special at the point of registration.

With the get_post_types() call, I'm only getting "special" back without any other characters.

tw2113 avatar Feb 06 '23 15:02 tw2113

Hey @tw2113 thanks for the quick feedback, I'm away for a couple of days but I'm going to retest this later this week.

I'm almost certain it was coming out double encoded (I got this reported from a user initially), so I'm going to try to recreate this and provide clearer steps.

rmorse avatar Feb 07 '23 16:02 rmorse

Noted, thanks.

tw2113 avatar Feb 07 '23 17:02 tw2113

@rmorse did you ever get this figured out, or is it still presenting some problems?

tw2113 avatar Oct 31 '23 23:10 tw2113

Hey @tw2113 , this issue was still presenting last time I checked, unfortunately I had to leave this alone for now but I think I'll revisit it in a couple of months.

rmorse avatar Nov 01 '23 01:11 rmorse

I'll leave the issue open for the moment then.

tw2113 avatar Nov 01 '23 01:11 tw2113