WordPress.org

Make WordPress Core

Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#32640 closed defect (bug) (invalid)

wp-db.php bug when activating plugin ("unexpected output" During Plugin Activation)

Reported by: s1nc1tycyph3r Owned by:
Milestone: Priority: normal
Severity: normal Version: 4.2.2
Component: Database Keywords: 2nd-opinion close
Focuses: Cc:
PR Number:

Description (last modified by SergeyBiryukov)

I'm A Developer Writing my latest wordpress plugin and discovered a bug with the /include/wp-db.php file in the latest version of wp!

upon activation of my plugin i'm developing i get the following message on the plugin activation screen

The plugin generated 9520 characters of unexpected output during activation. If you notice “headers already sent” messages, problems with syndication feeds or other issues, try deactivating or removing this plugin.

and i get the following debug errors
when using the https://wordpress.org/plugins/debug-plugin-activation-errors/
plugin

Warning:  Invalid argument supplied for foreach() in /home/tispgu/public_html/wp-testdomain/wp-includes/wp-db.php on line 1987
Warning:  Invalid argument supplied for foreach() in /home/tispgu/public_html/wp-testdomain/wp-includes/wp-db.php on line 2020
Warning:  Invalid argument supplied for foreach() in /home/tispgu/public_html/wp-testdomain/wp-includes/wp-db.php on line 2050
Warning:  Invalid argument supplied for foreach() in /home/tispgu/public_html/wp-testdomain/wp-includes/wp-db.php on line 2593
Warning:  Invalid argument supplied for foreach() in /home/tispgu/public_html/wp-testdomain/wp-includes/wp-db.php on line 1824
Warning:  array_keys() expects parameter 1 to be array, null given in /home/tispgu/public_html/wp-testdomain/wp-includes/wp-db.php on line 1829
Warning:  implode() [function.implode]: Invalid arguments passed in /home/tispgu/public_html/wp-testdomain/wp-includes/wp-db.php on line 1829

based on this error report i was able to determine the cause and location of the plugin activation issue to be with the /wp-includes/wp-db.php file
i was also able to resolve this bug by fixing the code in a couple of functions within that file

here are the changes i made to the code:

function code is contained in: function _insert_replace_helper( $table, $data, $format = null, $type = 'INSERT' )

line 1814
original code:

		if ( ! in_array( strtoupper( $type ), array( 'REPLACE', 'INSERT' ) ) ) {
			return false;
		}

line 1814
updated code:

		if ( !in_array( strtoupper( $type ), array( 'REPLACE', 'INSERT' ) ) || !is_array( $data )) {
			return false;
		}

function code is contained in: function delete( $table, $where, $where_format = null )

line 1907
original code:

		if ( ! is_array( $where ) ) {
			return false;
		}

line 1907
updated code

		if (!is_array( $where ) ) {
			return false;
		}

Change History (8)

#1 @SergeyBiryukov
4 years ago

  • Description modified (diff)

#2 follow-up: @dd32
4 years ago

This sounds like you're passing invalid data to $wpdb->insert(), or passing invalid data to another function that is ultimately passing it through to the DB layer.

Are you able to post a minimal plugin which duplicates the issue?

Last edited 4 years ago by dd32 (previous) (diff)

#3 in reply to: ↑ 2 @s1nc1tycyph3r
4 years ago

Replying to dd32:

This sounds like you're passing invalid data to $wpdb->insert(), or passing invalid data to another function that is ultimately passing it through to the DB layer.

Are you able to post a minimal plugin which duplicates the issue?

yes i just did as you suggested and i'm still getting the same issue

heres the
code im using for the minimal plugin

<?php
/**
 * @package Minimal Plugin
 * @version 1.0
 */
/*
Plugin Name: Minimal Plugin
Plugin URI: http://primagemedia.com/
Description: This Is A Minimal Plugin
Author: Michael Christopher Ingli
Version: 1.0
Author URI: http://www.primagemedia.com/
*/
global $minimalplugin_db_version;
$minimalplugin_db_version = '1.0';
// define Plugin Version
define( 'MINIMALPLUGIN_VERSION', $minimalplugin_db_version );
// define Plugin Url
define( 'MINIMALPLUGIN__PLUGIN_URL', plugin_dir_url( __FILE__ ) );
// define Plugin Dir
define( 'MINIMALPLUGIN__PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
// ensure ABSPATH IS Already Defined (Wordpress Should have Defined it already at this point)
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );

// Create and Define Plugin Install Function(Gets called On Plugin Activation! see register_activation_hook declaration at the end of this file)
function minimalplugin_install() {
	// ensure we define global $wpdb For this Function locally
	if (!isset($wpdb)) $wpdb = $GLOBALS['wpdb'];
	global $wpdb;
	global $minimalplugin_db_version;
	
	//global $wp_query;
	//define all the sql table names that our plugin will make use of where $wpdb->prefix usually is 'wp_'
	
	$minimalplugin_data_tablename=$wpdb->prefix . 'minimaltestdata';
	//$mapformadminemail_tablename = $wpdb->prefix.'mapform_adminemail'
	
	//get character collation to create our Sql Tables With
	$charset_collate = $wpdb->get_charset_collate();
	//define and Sql Tables Stucture
	
	$sql = "CREATE TABLE $minimalplugin_data_tablename (
  	id int(11) NOT NULL AUTO_INCREMENT,
  	testdataa varchar(255) NOT NULL,
	testdatab varchar(255) NOT NULL,
 	PRIMARY KEY  id (id)
	) $charset_collate;";
	//include require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); as this is where the dbDelta function is defined
	require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
	// create our Sql Tables Now
	dbDelta( $sql );

	// Add the db version
	add_option( 'minimalplugin_db_version', $minimalplugin_db_version );
}
// define our Sql Install Data Function(Gets called On Plugin Activation! see register_activation_hook declaration at the end of this file)
function minimalplugin_install_data() {
	// ensure we define global $wpdb For this Function locally
	if (!isset($wpdb)) $wpdb = $GLOBALS['wpdb'];
	global $wpdb;
	global $wp_query;
	
	$minimalplugin_data_tablename=$wpdb->prefix . 'minimaltestdata';
	$testdata=array(array('id'=>'1', 'testdataa'=>'mytestdataa', 'testdatab'=>'mytestdatab'),
					array('id'=>'2', 'testdataa'=>'mytestdataa2', 'testdatab'=>'mytestdatab2'),
					array('id'=>'3', 'testdataa'=>'mytestdataa3', 'testdatab'=>'mytestdatab3'));
for($i=0; $i<=sizeof($testdata); $i++)
{
	$wpdb->insert(
		$minimalplugin_data_tablename,
$testdata[$i]
	);
}

}
register_activation_hook( __FILE__, 'minimalplugin_install' );
register_activation_hook( __FILE__, 'minimalplugin_install_data' );
add_action('activated_plugin','save_error');
function save_error(){
file_put_contents(ABSPATH. 'wp-content/uploads/2015/error_activation.html', ob_get_contents());
}

?>

#4 follow-up: @dd32
4 years ago

  • Keywords 2nd-opinion close added
for($i=0; $i<=sizeof($testdata); $i++)
{
	$wpdb->insert(
		$minimalplugin_data_tablename,
$testdata[$i]
	);

sizeof returns the count of the array, in this case 3, however the indices are only 0, 1, and 2. So you're passing invalid data through (null) - use < rather than <=.

If you're not already developing with WP_DEBUG enabled,I'd highly suggest you do.

IMHO, passing invalid data here isn't a case we should protect against.

#5 in reply to: ↑ 4 @s1nc1tycyph3r
4 years ago

Replying to dd32:

for($i=0; $i<=sizeof($testdata); $i++)
{
	$wpdb->insert(
		$minimalplugin_data_tablename,
$testdata[$i]
	);

sizeof returns the count of the array, in this case 3, however the indices are only 0, 1, and 2. So you're passing invalid data through (null) - use < rather than <=.

If you're not already developing with WP_DEBUG enabled,I'd highly suggest you do.

IMHO, passing invalid data here isn't a case we should protect against.

ah i completely overlooked that! lol thx for pointing it out! it fixed most of the output errors
however i am still getting The plugin generated 362 characters of unexpected output during activation. If you notice “headers already sent” messages, problems with syndication feeds or other issues, try deactivating or removing this plugin. message but i am not getting any further
Warning: Invalid argument supplied for foreach() in /home/tispgu/public_html/wp-testdomain/wp-includes/wp-db.php on line 1987
Warning: Invalid argument supplied for foreach() in /home/tispgu/public_html/wp-testdomain/wp-includes/wp-db.php on line 2020
Warning: Invalid argument supplied for foreach() in /home/tispgu/public_html/wp-testdomain/wp-includes/wp-db.php on line 2050
Warning: Invalid argument supplied for foreach() in /home/tispgu/public_html/wp-testdomain/wp-includes/wp-db.php on line 2593
Warning: Invalid argument supplied for foreach() in /home/tispgu/public_html/wp-testdomain/wp-includes/wp-db.php on line 1824
Warning: array_keys() expects parameter 1 to be array, null given in /home/tispgu/public_html/wp-testdomain/wp-includes/wp-db.php on line 1829
Warning: implode() [function.implode]: Invalid arguments passed in /home/tispgu/public_html/wp-testdomain/wp-includes/wp-db.php on line 1829
message warnings!
and yes i do use WP_DEBUG while developing new plugins!

#6 @miqrogroove
4 years ago

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

You've also initialized the $testdata array incorrectly, as it does not contain a zero index. I suggest moving this discussion to the support forum.

#7 @miqrogroove
4 years ago

Ah, I might have read this incorrectly at 'id'=>'1' In any case, the ticket did not describe any bug in WordPress, but only errors generated by a plugin. I suggest trying to determine the exact cause before assuming there is a core problem.

#8 @miqrogroove
4 years ago

FWIW, the plugin only works one time. On successive attempts, the first error is caused by using dbdelta to re-create your primary key. The remaining three errors are caused by the plugin attempting to insert invalid values on the id column. These are normal errors caused by the plugin.

Note: See TracTickets for help on using tickets.