Make WordPress Core

Opened 5 years ago

Last modified 2 months ago

#16101 new defect (bug)

Numeric term fields are strings

Reported by: foofy Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version:
Component: Taxonomy Keywords: needs-patch needs-unit-tests
Focuses: Cc:


The numeric fields (term_id, parent, etc.) on term objects are strings. I only noticed this because term_exists() uses is_int() to determine if the $term value is an ID or slug.

Only ticket I could find about this is #5381.

sanitize_term() should fix this, but it bails early in the "raw" context. sanitize_term_field() sanitizes the numeric fields in every context. I don't see a reason for sanitize_term() to bail early so I made a patch that takes that out. The patch also adds some missing fields to the list of those to be sanitized and changes term_exists() to use is_numeric() (which will correctly identify strings containing only numbers) instead of is_int().

Attachments (1)

sanitize-numeric-term-fields.patch (1.4 KB) - added by foofy 5 years ago.

Download all attachments as: .zip

Change History (13)

#1 @scribu
5 years ago

From the PHP manual on is_numeric():

Finds whether the given variable is numeric. Numeric strings consist of optional sign, any number of digits, optional decimal part and optional exponential part. Thus +0123.45e6 is a valid numeric value. Hexadecimal notation (0xFF) is allowed too but only without sign, decimal and exponential part.

This could cause subtle bugs.

#2 @foofy
5 years ago

  • Cc foofy@… added

I think it would be fine to leave that as is_int() since the problem goes away if the term objects are properly sanitized.

#3 follow-up: @mdawaffe
5 years ago

  • Keywords dev-feedback added
  • Milestone changed from Awaiting Review to Future Release

Can use ctype_digit( $term ) without making changes to sanitize_term*().

Casting everything to (int) could change the output of XML-RPC requests which can break clients, so we need to be super careful there.

#4 in reply to: ↑ 3 @mdawaffe
5 years ago

Replying to mdawaffe:

Can use ctype_digit( $term ) without making changes to sanitize_term*().

Nacin tells me some hosts disable Ctype, which is ridiculous (on the hosts' parts, not on Nacin's).

#5 @iandunn
3 years ago

  • Cc ian_dunn@… added
  • Keywords changed from has-patch dev-feedback to has-patch dev-feedback

This just bit me in the ass, because I took the term_id from get_terms() and passed it to get_term_link() as $term. get_term_link() assumed that $term was a slug because it failed is_int(), and since there's no term named "237", it returned a WP_Error().

It seems to me like casting the values to int in get_term*() is the proper fix, even if it requires patching/testing XML-RPC code. If there's a consensus behind that approach, I'll try to find time to write and test a new patch in the next couple weeks.

Version 0, edited 3 years ago by iandunn (next)

#7 @wonderboymusic
2 years ago

  • Keywords needs-patch added; has-patch dev-feedback removed

#8 @SergeyBiryukov
14 months ago

#29756 was marked as a duplicate.

#9 @boonebgorges
10 months ago

  • Keywords needs-unit-tests added

This ticket was mentioned in Slack in #core by boone. View the logs.

2 months ago

This ticket was mentioned in Slack in #docs by majemedia. View the logs.

2 months ago

#12 @majemedia
2 months ago

Can the return values for term_exists have a note added to documentation?


Note: See TracTickets for help on using tickets.