Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/mw-wp-form/classes/abstract/class.form-field.php
+++ b/mw-wp-form/classes/abstract/class.form-field.php
@@ -129,7 +129,7 @@
$args = $this->set_names();
if ( empty( $args['shortcode_name'] ) || empty( $args['display_name'] ) ) {
- exit( get_class() . '::set_names() returns not right values. Returned values is ' . serialize( $args ) . ' now.' );
+ exit( get_class( $this ) . '::set_names() returns not right values. Returned values is ' . serialize( $args ) . ' now.' );
}
$this->shortcode_name = $args['shortcode_name'];
--- a/mw-wp-form/classes/abstract/class.validation-rule.php
+++ b/mw-wp-form/classes/abstract/class.validation-rule.php
@@ -88,8 +88,8 @@
*/
public function getName() {
MWF_Functions::deprecated_message(
- get_class() . '::getName()',
- get_class() . '::get_name()'
+ get_class( $this ) . '::getName()',
+ get_class( $this ) . '::get_name()'
);
return $this->get_name();
}
--- a/mw-wp-form/classes/controllers/class.deprecation-notice.php
+++ b/mw-wp-form/classes/controllers/class.deprecation-notice.php
@@ -0,0 +1,148 @@
+<?php
+/**
+ * @package mw-wp-form
+ * @author websoudan
+ * @license GPL-2.0+
+ */
+
+/**
+ * MW_WP_Form_Deprecation_Notice_Controller
+ *
+ * Displays a deprecation notice across every admin page when forms that use
+ * shortcodes scheduled for removal exist. Split out from the form edit
+ * controller so that the notice appears even when administrators are not
+ * currently editing a form.
+ */
+class MW_WP_Form_Deprecation_Notice_Controller {
+
+ /**
+ * Cache key for the list of forms using shortcodes scheduled for removal.
+ */
+ const CACHE_KEY = 'mwform_deprecated_shortcodes_forms';
+
+ /**
+ * Constructor.
+ */
+ public function __construct() {
+ add_action( 'admin_notices', array( $this, '_notice' ) );
+ add_action( 'save_post_' . MWF_Config::NAME, array( $this, '_invalidate_cache' ) );
+ add_action( 'deleted_post', array( $this, '_invalidate_cache' ) );
+ add_action( 'trashed_post', array( $this, '_invalidate_cache' ) );
+ add_action( 'untrashed_post', array( $this, '_invalidate_cache' ) );
+ }
+
+ /**
+ * Display an admin notice listing all forms that use shortcodes
+ * scheduled for removal in a future release.
+ */
+ public function _notice() {
+ if ( ! current_user_can( MWF_Config::CAPABILITY ) ) {
+ return;
+ }
+
+ $affected_forms = $this->_get_forms_using_deprecated_shortcodes();
+ if ( empty( $affected_forms ) ) {
+ return;
+ }
+
+ $list_items = array();
+ foreach ( $affected_forms as $form ) {
+ $edit_link = get_edit_post_link( $form->ID );
+ $title = '' !== (string) $form->post_title
+ ? $form->post_title
+ : __( '(no title)', 'mw-wp-form' );
+
+ if ( $edit_link ) {
+ $list_items[] = sprintf(
+ '<a href="%1$s">%2$s</a>',
+ esc_url( $edit_link ),
+ esc_html( $title )
+ );
+ } else {
+ $list_items[] = esc_html( $title );
+ }
+ }
+
+ ?>
+ <div class="notice notice-warning">
+ <p>
+ <strong><?php esc_html_e( 'MW WP Form: Notice of feature removal', 'mw-wp-form' ); ?></strong><br>
+ <?php
+ printf(
+ /* translators: 1: Version number, 2: Planned year of removal. */
+ esc_html__( 'The [mwform_file] and [mwform_image] shortcodes will be removed in version %1$s (planned for release within %2$s).', 'mw-wp-form' ),
+ '5.2',
+ '2026'
+ );
+ ?>
+ </p>
+ <p>
+ <?php esc_html_e( 'The following form(s) currently use these shortcodes:', 'mw-wp-form' ); ?>
+ <?php echo implode( ', ', $list_items ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Individual items escaped above. ?>
+ </p>
+ </div>
+ <?php
+ }
+
+ /**
+ * Return mw-wp-form posts whose content contains shortcodes scheduled
+ * for removal.
+ *
+ * @return array<object{ID:int,post_title:string}>
+ */
+ protected function _get_forms_using_deprecated_shortcodes() {
+ $cached = get_transient( self::CACHE_KEY );
+ if ( false !== $cached ) {
+ return $cached;
+ }
+
+ global $wpdb;
+
+ $like_file = '%' . $wpdb->esc_like( '[mwform_file' ) . '%';
+ $like_image = '%' . $wpdb->esc_like( '[mwform_image' ) . '%';
+
+ $candidates = $wpdb->get_results(
+ $wpdb->prepare(
+ "SELECT ID, post_title, post_content FROM {$wpdb->posts}
+ WHERE post_type = %s
+ AND post_status NOT IN ( 'trash', 'auto-draft' )
+ AND ( post_content LIKE %s OR post_content LIKE %s )
+ ORDER BY post_title ASC",
+ MWF_Config::NAME,
+ $like_file,
+ $like_image
+ )
+ );
+
+ $results = array();
+ if ( is_array( $candidates ) ) {
+ foreach ( $candidates as $row ) {
+ // LIKE can match other shortcodes whose name begins with
+ // "mwform_file" or "mwform_image" (e.g. "mwform_filepicker").
+ // Re-check with a shortcode-aware regex.
+ if ( preg_match( '/[(mwform_file|mwform_image)(s|])/', (string) $row->post_content ) ) {
+ $results[] = (object) array(
+ 'ID' => (int) $row->ID,
+ 'post_title' => (string) $row->post_title,
+ );
+ }
+ }
+ }
+
+ set_transient( self::CACHE_KEY, $results, HOUR_IN_SECONDS );
+ return $results;
+ }
+
+ /**
+ * Invalidate the cached list of forms using deprecated shortcodes.
+ * Fires when a form is saved, deleted, trashed, or untrashed.
+ *
+ * @param int $post_id Post ID.
+ */
+ public function _invalidate_cache( $post_id = 0 ) {
+ if ( $post_id && MWF_Config::NAME !== get_post_type( $post_id ) ) {
+ return;
+ }
+ delete_transient( self::CACHE_KEY );
+ }
+}
--- a/mw-wp-form/classes/models/class.csrf.php
+++ b/mw-wp-form/classes/models/class.csrf.php
@@ -40,7 +40,18 @@
static::$token = ! $saved_token ? static::generate_token() : $saved_token;
if ( ! $saved_token && ! headers_sent() ) {
$secure = apply_filters( 'mwform_secure_cookie', is_ssl() );
- setcookie( static::KEY, static::$token, 0, COOKIEPATH, COOKIE_DOMAIN, $secure, true );
+ setcookie(
+ static::KEY,
+ static::$token,
+ array(
+ 'expires' => 0,
+ 'path' => COOKIEPATH,
+ 'domain' => COOKIE_DOMAIN,
+ 'secure' => $secure,
+ 'httponly' => true,
+ 'samesite' => 'Lax',
+ )
+ );
}
}
--- a/mw-wp-form/classes/models/class.parser.php
+++ b/mw-wp-form/classes/models/class.parser.php
@@ -134,6 +134,10 @@
return;
}
+ if ( 'publish' !== $post->post_status || post_password_required( $post ) ) {
+ return;
+ }
+
return $this->_get_post_property( $post, $matches[1] );
}
--- a/mw-wp-form/classes/models/class.session.php
+++ b/mw-wp-form/classes/models/class.session.php
@@ -44,7 +44,18 @@
$secure = apply_filters( 'mwform_secure_cookie', is_ssl() );
try {
set_error_handler( array( 'MW_WP_Form_Session', 'error_handler' ) );
- setcookie( $this->name, $session_id, 0, COOKIEPATH, COOKIE_DOMAIN, $secure, true );
+ setcookie(
+ $this->name,
+ $session_id,
+ array(
+ 'expires' => 0,
+ 'path' => COOKIEPATH,
+ 'domain' => COOKIE_DOMAIN,
+ 'secure' => $secure,
+ 'httponly' => true,
+ 'samesite' => 'Lax',
+ )
+ );
} catch ( ErrorException $e ) {
// No process...
}
--- a/mw-wp-form/classes/validation-rules/class.maximagesize.php
+++ b/mw-wp-form/classes/validation-rules/class.maximagesize.php
@@ -56,6 +56,7 @@
$filepath = MW_WP_Form_Directory::generate_user_filepath( $form_id, $name, $value );
}
+ $imagesize = false;
if ( file_exists( $filepath ) && exif_imagetype( $filepath ) ) {
$imagesize = getimagesize( $filepath );
} else {
@@ -70,7 +71,7 @@
'message' => __( 'This image size is too big.', 'mw-wp-form' ),
);
$options = array_merge( $defaults, $options );
- if ( $is_error || $imagesize[0] > $options['width'] || $imagesize[1] > $options['height'] ) {
+ if ( $is_error || ( is_array( $imagesize ) && ( $imagesize[0] > $options['width'] || $imagesize[1] > $options['height'] ) ) ) {
return $options['message'];
}
}
--- a/mw-wp-form/mw-wp-form.php
+++ b/mw-wp-form/mw-wp-form.php
@@ -3,7 +3,7 @@
* Plugin Name: MW WP Form
* Plugin URI: https://mw-wp-form.web-soudan.co.jp
* Description: MW WP Form is shortcode base contact form plugin. This plugin have many features. For example you can use many validation rules, inquiry data saving, and chart aggregation using saved inquiry data.
- * Version: 5.1.2
+ * Version: 5.1.3
* Requires at least: 6.0
* Requires PHP: 8.0
* Author: websoudan
@@ -80,6 +80,7 @@
add_action( 'admin_menu', array( $this, '_admin_menu_for_chart' ) );
add_action( 'admin_menu', array( $this, '_admin_menu_for_inquiry_data_list' ) );
add_action( 'current_screen', array( $this, '_current_screen' ) );
+ new MW_WP_Form_Deprecation_Notice_Controller();
} elseif ( ! is_admin() ) {
new MW_WP_Form_Main_Controller();
}