Make WordPress Core

Opened 15 years ago

Closed 15 years ago

Last modified 15 years ago

#6894 closed defect (bug) (fixed)

2.5.1 only - some post text (persian) causes timeout on publish (not save)

Reported by: jeremyclarke's profile jeremyclarke Owned by: westi's profile westi
Milestone: 2.6 Priority: high
Severity: critical Version: 2.5
Component: Administration Keywords: has-patch needs-testing
Focuses: Cc:

Description

I run a set of translations of our sites main english content. I recently upgraded each of the translation wp installs from 2.3.3 to 2.5.1 and it went great for almost all the languages.

For some reason the Persian/Farsi version is having insane problems publishing. Some content will go through fine, but if certain characters are present any attempt to publish the post causes cpu to go up to 100% (using top through ssh) and hang until php times out (I tried 30s and 60s timeouts, made no difference, it is a powerful new quadcore server with a seperate quadcore db server, so it's definitely not a lack of resources).

If you want to test this on your install you can use this text as an example

http://pastie.caboo.se/189915

(put the text below TITLE as the title and the text below CONTENT as the post content), you probably can't read it but it's just some normal Farsi text (i can't read it either). My database is utf8_unicode_ci (also tested on utf8_persian_ci), which you'll need to have also for the text to work in general.

Note that saving is not effected at all, both autosave and manually saving a problematic post works immediately with no appreciable problems or lags.

When the timeouts happen they throw fatal errors for all kinds of different parts of the code in wp-includes/post.php, wp-includes/wp-db.php etc, including some line numbers that dont' exist (line 1237 of wp-db.php for example).

They look like this:

Fatal error: Maximum execution time of 30 seconds exceeded in /xxx/wp-includes/wp-db.php on line 169

A given problematic title+content (like the one at http://pastie.caboo.se/189915 ) will consistently cause this to happen across several blogs I tested, but only if they were upgraded to 2.5.1. Sites that are 2.5.0 or less are totally fine and publish quickly like normal.

I tried it on a fresh copy of 2.5.1 and it did not work. (this happens with no plugins installed and the title+content are enough to trigger it, I dont' think categories etc come into play). Slight variations on the text sometimes allow it through, though changing it to english always works.

One thing that may be relevant is that switching the 2.5.0 files back in (which triggers an 'upgrade database' script of some kind and shows me the upgrade screen and afterwards shows the "you need to upgrade to 2.5.1" message) does NOT fix the problem, the blog must never have known 2.5.1 to be immune, which makes me think it might be one of the database changes (which I'm not that familiar with).

Any leads about what might be causing it are appreciated. If someone could confirm that the text causes problems that would also be great. Thanks.

Attachments (1)

6894.diff (1007 bytes) - added by westi 15 years ago.
A patch for one issue (probably of many)

Download all attachments as: .zip

Change History (10)

#1 @westi
15 years ago

  • Version changed from 2.5.1 to 2.5

Looks like this is caused by dodgy implementation of $wpdb->prepare().

e.g. from wp-includes/post.php

if ( 'draft' != $post_status ) {
		$post_name_check = $wpdb->get_var($wpdb->prepare("SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type = %s AND ID != %d AND post_parent = %d LIMIT 1", $post_name, $post_type, $post_ID, $post_parent));

		if ($post_name_check || in_array($post_name, $wp_rewrite->feeds) ) {
			$suffix = 2;
			do {
				$alt_post_name = substr($post_name, 0, 200-(strlen($suffix)+1)). "-$suffix";
				// expected_slashed ($alt_post_name, $post_name, $post_type)
				$post_name_check = $wpdb->get_var($wpdb->prepare("SELECT post_name FROM $wpdb->posts WHERE post_name = '$alt_post_name' AND post_type = '$post_type' AND ID != %d AND post_parent = %d LIMIT 1", $post_ID, $post_parent));
				$suffix++;
			} while ($post_name_check);
			$post_name = $alt_post_name;
		}
	}

Things are being substituted into the string passed in, which is passed to vsprintf - if these contain '%...' then the substitution is going to get all broken

@westi
15 years ago

A patch for one issue (probably of many)

#2 @westi
15 years ago

  • Cc markjaquith added
  • Keywords has-patch needs-testing added
  • Owner changed from anonymous to westi
  • Status changed from new to assigned

We need to review for other issues like this that may have crept in due to wpdb->prepare.

#3 @ryan
15 years ago

Yeah, we definitely need a review. If we substitute one field in a query we have to do all fields.

Since all of the fields in that query shouldn't have characters that need to be escaped, I don't think we have to worry about double escaping. Looks good to me.

#4 @jeremyclarke
15 years ago

Great work westi. It fixed the problem I was having with the persian site. I wish I'd thought of the sprintf as the problem earlier.

I still have no idea why the problem didn't exist in 2.5.0 but did in 2.5.1, I must have been tricking myself with fresh databases or something. (actually, it suddenly makes sense to me)

Thanks for the quick action, I'm off to patch my other unicode-needy sites :)

#5 @ryan
15 years ago

(In [7876]) Fix post name check prepare. Props westi. see #6894

#6 @ryan
15 years ago

(In [7877]) Fix post name check prepare. Props westi. see #6894 for 2.5

#7 @ryan
15 years ago

  • Resolution set to fixed
  • Status changed from assigned to closed

#8 @ryan
15 years ago

  • Milestone changed from 2.5.2 to 2.9

Milestone 2.5.2 deleted

#9 @westi
15 years ago

  • Milestone changed from 2.9 to 2.6
Note: See TracTickets for help on using tickets.