PluginProbe
Code Engine – PHP Snippets, AI Functions & Automation for WordPress / 0.5.3
Code Engine – PHP Snippets, AI Functions & Automation for WordPress v0.5.3
0.5.6 0.5.5 0.5.4 0.5.3 0.5.2 0.5.1 0.5.0 0.4.9 0.4.8 0.4.7 0.4.6 trunk 0.0.1 0.0.2 0.2.8 0.2.9 0.3.0 0.3.1 0.3.2 0.3.3 0.3.4 0.3.5 0.3.6 0.3.7 0.3.8 All 32 releases
← All changes | classes/core.php +47 -37 0.5.40.5.3 View file →
@@ -362,17 +362,35 @@
362 362 'values' => $snippet['functionArgsDict'] // Contains the default values of the arguments
363 363 ];
364 364 }
365 365
366 - // Arguments used to be sanitized into PHP-literal strings here (quoting,
367 - // esc_sql, var_export) so they could be concatenated into a string of PHP and
368 - // eval-ed. That is gone: the function is now called with call_user_func_array
369 - // (see below), so values are passed as data and need no literal-formatting.
370 - // The old formatting also prefixed argument keys with "$" via sanitize_arg,
371 - // which stored the provided value under "$name" while the call read "name", so
372 - // provided arguments never reached the function. Passing the raw values through
373 - // fixes both issues at once.
366 + // Sanitize all the arguments if the option is enabled
367 + if ( $this->get_option( 'sanitize_arguments', true ) ) {
374 368
369 + if ( $args ) {
370 + foreach ( $args as $name => $value ) {
371 + list( $sanitizedName, $sanitizedValue ) = $this->sanitize_arg( $name, $value );
372 + unset( $args[$name] );
373 +
374 + $args[$sanitizedName] = $sanitizedValue;
375 + }
376 + }
377 +
378 + foreach ( $params['values'] as $name => $value ) {
379 +
380 + if( array_key_exists( 'input', $value) ) {
381 + list( $sanitizedInputName, $sanitizedInputValue ) = $this->sanitize_arg( $name, $value['input'], $value['type'] );
382 + $params['values'][$sanitizedInputName]['input'] = $sanitizedInputValue;
383 + }
384 +
385 + if( array_key_exists( 'default', $value) ) {
386 + list( $sanitizedDefaultValueName, $sanitizedDefaultValue ) = $this->sanitize_arg( $name, $value['default'], $value['type'] );
387 + $params['values'][$sanitizedDefaultValueName]['default'] = $sanitizedDefaultValue;
388 + }
389 + }
390 +
391 + }
392 +
375 393 // Make sure the function is existing and is the one in the snippet
376 394 if ( empty( $params['code'] ) ) {
377 395 throw new Exception( 'Code Engine: The snippet code appears to be empty.' );
378 396 }
@@ -418,57 +436,49 @@
418 436 // If already defined, just prepare to call the function without redefining it
419 437 $params['code'] = '';
420 438 }
421 439
422 - // Resolve the arguments as REAL PHP values, in the function's declared order.
423 - // The previous version concatenated each value into a string of PHP and eval-ed
424 - // the call, which broke on any string or edge-case value with a parse error
425 - // ("syntax error, unexpected token ')'"). call_user_func_array passes them as
426 - // data, so no value can ever corrupt the call syntax.
427 - $callArgs = [];
428 - foreach ( $params['args'] as $arg ) {
429 - $value = null; // Not provided and no default -> null.
430 - if ( array_key_exists( $arg, $params['values'] ) ) {
440 + // Prepare the code to be executed
441 + $params['code'] .= "\n\$mwcode_result = {$params['name']}(";
442 + foreach ( $params['args'] as $index => $arg ) {
443 + $value = 'null'; // In case the argument is not provided it will be null
444 +
445 + if ( array_key_exists( $arg, $params['values'] ) ) { // Avoid warnings if the argument is not provided
446 +
447 + // If the argument is provided, use it, if not use the default value
431 448 if ( !empty( $params['values'][$arg]['input'] ) ) {
432 449 $value = $params['values'][$arg]['input'];
450 +
433 451 } else if ( !empty( $params['values'][$arg]['default'] ) ) {
434 452 $value = $params['values'][$arg]['default'];
435 453 }
436 454 }
437 - // An array-typed argument can arrive as a string like "[1, 2, 3]"; turn it
438 - // into a real array so the function receives what its signature expects.
439 - if ( ( $params['values'][$arg]['type'] ?? null ) === 'array' && is_string( $value ) ) {
440 - $decoded = json_decode( $value, true );
441 - $value = is_array( $decoded ) ? $decoded : array_map( 'trim', explode( ',', trim( $value, "[] \t\n\r" ) ) );
455 +
456 + $params['code'] .= "{$value}";
457 + if ( $index < count( $params['args'] ) - 1 ) {
458 + $params['code'] .= ', ';
442 459 }
443 - $callArgs[] = $value;
444 460 }
445 461
462 + $params['code'] .= ");\necho print_r(\$mwcode_result, true);";
463 +
446 464 $error = null;
447 465 $output = null;
448 -
466 +
449 467 try {
450 468 ob_start();
451 - // $params['code'] holds the function definition (empty if it was already
452 - // defined earlier this request). Declare it, then invoke it as data.
453 - if ( $params['code'] !== '' ) {
454 - eval( $params['code'] );
455 - }
456 - $mwcode_result = call_user_func_array( $params['name'], $callArgs );
457 - echo print_r( $mwcode_result, true );
469 + eval( $params['code'] );
458 470 $output = ob_get_clean();
459 -
460 - if ( $params['test'] ) {
471 +
472 + if ( $params['test'] ){
461 473 $output = explode( "\n", $output );
462 474 }
463 -
475 +
464 476 } catch ( Throwable $e ) {
465 477 //$this->log('Code Engine: Error executing the function: ' . $e->getMessage());
466 478 $error = new Exception(' Error executing the function, ' . $e->getMessage());
467 479
468 - if ( ob_get_level() > 0 ) {
469 - ob_end_clean();
470 - }
480 + ob_clean();
471 481 } finally {
472 482 restore_error_handler();
473 483 }
474 484