Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/wpforms-lite/includes/admin/builder/functions.php
+++ b/wpforms-lite/includes/admin/builder/functions.php
@@ -684,7 +684,8 @@
* @since 1.6.6
*
* @param string $inner Inner HTML to wrap.
- * @param array $args Array of arguments.
+ * @param array $args Array of arguments. Supports `group`, `unfoldable`, `default`, `class`,
+ * `borders`, `title`, `title_badge` (trusted HTML shown after the title), `description`.
* @param bool $do_echo Flag to display.
*
* @return string|null
@@ -711,7 +712,9 @@
if ( ! empty( $args['title'] ) ) {
$chevron = $unfoldable ? '<i class="fa fa-chevron-circle-right"></i>' : '';
- $output .= '<div class="wpforms-panel-fields-group-title">' . esc_html( $args['title'] ) . $chevron . '</div>';
+ // Caller-controlled trusted markup (e.g. a "New" badge) shown after the title.
+ $title_badge = ! empty( $args['title_badge'] ) ? $args['title_badge'] : '';
+ $output .= '<div class="wpforms-panel-fields-group-title">' . esc_html( $args['title'] ) . $title_badge . $chevron . '</div>';
}
if ( ! empty( $args['description'] ) ) {
--- a/wpforms-lite/includes/admin/builder/panels/class-settings.php
+++ b/wpforms-lite/includes/admin/builder/panels/class-settings.php
@@ -10,6 +10,7 @@
}
use WPFormsAdminFormsTags;
+use WPFormsIntegrationsAiMcpAiMcp;
/**
* Settings management panel.
@@ -219,6 +220,8 @@
$this->general_setting_advanced();
+ $this->ai_mcp_section();
+
echo '</div>';
/*
@@ -380,6 +383,43 @@
]
);
}
+
+ /**
+ * Output the AI MCP section.
+ *
+ * Promotes the WordPress Abilities API + WPForms MCP bridge and exposes the write-access
+ * toggle inside the builder, mirroring the Tools → AI MCP tab. The toggle input is
+ * intentionally name-less, so it never enters the serialized form state and cannot be
+ * picked up by the form save / undo-redo flow — it is a site setting, not form data.
+ *
+ * @since 1.10.2.1
+ */
+ private function ai_mcp_section() {
+
+ // Without the Abilities API (WP 6.9+) no WPForms ability registers, so the toggle would gate nothing.
+ if ( ! wpforms_current_user_can() || ! function_exists( 'wp_register_ability' ) ) {
+ return;
+ }
+
+ $inner = wpforms_render(
+ 'admin/tools/ai-mcp',
+ AiMcp::get_template_data( 'wpforms-ai-mcp-page-builder' ),
+ true
+ );
+
+ // Open by default for the initial release; a later release will ship it collapsed.
+ wpforms_panel_fields_group(
+ $inner,
+ [
+ 'borders' => [ 'top' ],
+ 'unfoldable' => true,
+ 'group' => 'settings_ai_mcp',
+ 'title' => esc_html__( 'AI MCP', 'wpforms-lite' ),
+ 'title_badge' => '<span class="wpforms-badge wpforms-badge-sm wpforms-badge-inline wpforms-badge-rounded wpforms-badge-green">' . esc_html__( 'New', 'wpforms-lite' ) . '</span>',
+ 'default' => 'opened',
+ ]
+ );
+ }
}
new WPForms_Builder_Panel_Settings();
--- a/wpforms-lite/includes/emails/class-emails.php
+++ b/wpforms-lite/includes/emails/class-emails.php
@@ -305,22 +305,75 @@
public function get_headers() {
if ( ! $this->headers ) {
- $this->headers = "From: {$this->get_from_name()} <{$this->get_from_address()}>rn";
-
- if ( $this->get_reply_to() ) {
- $this->headers .= $this->reply_to_name ?
- "Reply-To: {$this->reply_to_name} <{$this->get_reply_to()}>rn" :
- "Reply-To: {$this->get_reply_to()}rn";
+ $from_name = $this->sanitize_email_header_name( (string) $this->get_from_name() );
+ $from_address = $this->sanitize_email_header( (string) $this->get_from_address() );
+ $reply_to = $this->sanitize_email_header( (string) $this->get_reply_to() );
+ $cc = $this->sanitize_email_header( (string) $this->get_cc() );
+
+ $this->headers = "From: {$from_name} <{$from_address}>rn";
+
+ if ( $reply_to ) {
+ $reply_to_name = $this->sanitize_email_header_name( (string) $this->reply_to_name );
+
+ $this->headers .= $reply_to_name ?
+ "Reply-To: {$reply_to_name} <{$reply_to}>rn" :
+ "Reply-To: {$reply_to}rn";
}
- if ( $this->get_cc() ) {
- $this->headers .= "Cc: {$this->get_cc()}rn";
+ if ( $cc ) {
+ $this->headers .= "Cc: {$cc}rn";
}
$this->headers .= "Content-Type: {$this->get_content_type()}; charset=utf-8rn";
}
- return apply_filters( 'wpforms_email_headers', $this->headers, $this );
+ /**
+ * Filter the email headers.
+ *
+ * @since 1.1.3
+ *
+ * @param string $headers Email headers.
+ * @param WPForms_WP_Emails $this Emails instance.
+ */
+ return (string) apply_filters( 'wpforms_email_headers', $this->headers, $this ); // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName
+ }
+
+ /**
+ * Sanitize a value for safe use as an email header.
+ *
+ * Replaces line breaks with a space to prevent email header (CRLF) injection,
+ * using the same strategy as the email subject. Address and CC slots use this
+ * method so their commas (recipient separators) are preserved.
+ *
+ * @since 1.10.2.1
+ *
+ * @param string $value Header value to sanitize.
+ *
+ * @return string Header value with line breaks replaced by spaces.
+ */
+ private function sanitize_email_header( string $value ): string {
+
+ return trim( str_replace( [ "rn", "r", "n" ], ' ', $value ) );
+ }
+
+ /**
+ * Sanitize a value for safe use as an email header display name.
+ *
+ * On top of neutralizing line breaks, this strips the characters wp_mail()
+ * treats as address-list delimiters when it re-parses the assembled header:
+ * commas (it splits Reply-To/Cc/Bcc on them) and angle brackets (address
+ * delimiters). RFC quoting is not enough because wp_mail() ignores it, so a
+ * comma left in a display name would inject an extra recipient.
+ *
+ * @since 1.10.2.1
+ *
+ * @param string $name Display name to sanitize.
+ *
+ * @return string Display name safe to embed in a From/Reply-To header.
+ */
+ private function sanitize_email_header_name( string $name ): string {
+
+ return trim( str_replace( [ ',', '<', '>' ], '', $this->sanitize_email_header( $name ) ) );
}
/**
--- a/wpforms-lite/src/Admin/Tools/Views/AiMcp.php
+++ b/wpforms-lite/src/Admin/Tools/Views/AiMcp.php
@@ -74,48 +74,10 @@
*/
public function display(): void {
- $user_id = get_current_user_id();
-
echo wpforms_render( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
'admin/tools/ai-mcp',
- [
- 'state' => $this->resolve_wpvibe_state(),
- 'is_write_enabled' => (bool) wpforms_setting( AiMcpIntegration::SETTING_KEY, false ),
- 'is_pro' => wpforms()->is_pro(),
- 'wpvibe_download_url' => AiMcpIntegration::WPVIBE_DOWNLOAD_URL,
- 'wpvibe_basename' => AiMcpIntegration::WPVIBE_BASENAME,
- 'wpvibe_setup_url' => admin_url( 'admin.php?page=' . AiMcpIntegration::WPVIBE_PAGE_SLUG ),
- 'has_visited_wpvibe' => $user_id && (bool) get_user_meta( $user_id, AiMcpIntegration::USER_META_VISITED_WPVIBE, true ),
- 'docs_url' => 'https://wpforms.com/docs/using-wpforms-with-ai-assistants/',
- ],
+ AiMcpIntegration::get_template_data(),
true
);
}
-
- /**
- * Detect whether WPVibe is not installed, installed but inactive, or active.
- *
- * @since 1.10.2
- *
- * @return string One of 'not_installed', 'installed_inactive', 'active'.
- */
- private function resolve_wpvibe_state(): string {
-
- if ( ! function_exists( 'is_plugin_active' ) ) {
- include_once ABSPATH . 'wp-admin/includes/plugin.php';
- }
-
- $basename = AiMcpIntegration::WPVIBE_BASENAME;
- $plugins = get_plugins();
-
- if ( ! array_key_exists( $basename, $plugins ) ) {
- return 'not_installed';
- }
-
- if ( ! is_plugin_active( $basename ) ) {
- return 'installed_inactive';
- }
-
- return 'active';
- }
}
--- a/wpforms-lite/src/Emails/Mailer.php
+++ b/wpforms-lite/src/Emails/Mailer.php
@@ -362,13 +362,16 @@
*/
public function get_headers() {
- $this->headers = "From: {$this->get_from_name()} <{$this->get_from_address()}>rn";
+ $from_name = $this->sanitize_email_header_name( (string) $this->get_from_name() );
+ $from_address = $this->sanitize_email_header( (string) $this->get_from_address() );
+ $reply_to = $this->sanitize_email_header( (string) $this->get_reply_to_address() );
+ $cc = $this->sanitize_email_header( (string) $this->get_cc_address() );
- if ( $this->get_reply_to_address() ) {
- $this->headers .= "Reply-To: {$this->get_reply_to_address()}rn";
- }
+ $this->headers = "From: {$from_name} <{$from_address}>rn";
- $cc = $this->get_cc_address();
+ if ( $reply_to ) {
+ $this->headers .= "Reply-To: {$reply_to}rn";
+ }
if ( $cc ) {
$this->headers .= "Cc: {$cc}rn";
@@ -384,7 +387,46 @@
* @param string $headers Email headers.
* @param Mailer $this Mailer instance.
*/
- return apply_filters( 'wpforms_emails_mailer_get_headers', $this->headers, $this );
+ return (string) apply_filters( 'wpforms_emails_mailer_get_headers', $this->headers, $this );
+ }
+
+ /**
+ * Sanitize a value for safe use as an email header.
+ *
+ * Replaces line breaks with a space to prevent email header (CRLF) injection,
+ * using the same strategy as the email subject. Address and CC slots use this
+ * method so their commas (recipient separators) are preserved.
+ *
+ * @since 1.10.2.1
+ *
+ * @param string $value Header value to sanitize.
+ *
+ * @return string Header value with line breaks replaced by spaces.
+ */
+ private function sanitize_email_header( string $value ): string {
+
+ return trim( str_replace( [ "rn", "r", "n" ], ' ', $value ) );
+ }
+
+ /**
+ * Sanitize a value for safe use as an email header display name.
+ *
+ * On top of neutralizing line breaks, this strips the characters wp_mail()
+ * treats as address-list delimiters when it re-parses the assembled header:
+ * commas (it splits Reply-To/Cc/Bcc on them) and angle brackets (address
+ * delimiters). RFC quoting is not enough because wp_mail() ignores it, so a
+ * comma left in a display name would inject an extra recipient. Declared
+ * protected because the Notifications subclass sanitizes the Reply-To name.
+ *
+ * @since 1.10.2.1
+ *
+ * @param string $name Display name to sanitize.
+ *
+ * @return string Display name safe to embed in a From/Reply-To header.
+ */
+ protected function sanitize_email_header_name( string $name ): string {
+
+ return trim( str_replace( [ ',', '<', '>' ], '', $this->sanitize_email_header( $name ) ) );
}
/**
--- a/wpforms-lite/src/Emails/Notifications.php
+++ b/wpforms-lite/src/Emails/Notifications.php
@@ -961,6 +961,7 @@
// In these contexts, we need to check if the smart tag is allowed.
$address_context = [
'notification-from',
+ 'notification-reply-to',
];
// Check if the smart tag is allowed AND if the context is allowed.
@@ -1111,6 +1112,9 @@
$matches = [];
if ( preg_match( $regex, $reply_to, $matches ) ) {
+ // The display name accepts any field value and is made header-safe by
+ // sanitize_email_header_name() below, so it must not run through the
+ // address-field validation that the 'notification-reply-to' context applies.
$reply_to_name = $this->sanitize( $matches[1] );
$reply_to = trim( $matches[2], '<> ' );
}
@@ -1124,7 +1128,7 @@
}
if ( $reply_to_name ) {
- $reply_to = "$reply_to_name <{$reply_to}>";
+ $reply_to = $this->sanitize_email_header_name( $reply_to_name ) . " <{$reply_to}>";
}
/**
--- a/wpforms-lite/src/Integrations/AiMcp/AiMcp.php
+++ b/wpforms-lite/src/Integrations/AiMcp/AiMcp.php
@@ -167,57 +167,113 @@
}
/**
- * Detect whether the current request is rendering the AI MCP tab.
- *
- * @since 1.10.2
- *
- * @return bool
- */
- private function is_ai_mcp_tab(): bool {
-
- // phpcs:disable WordPress.Security.NonceVerification.Recommended
- $page = isset( $_GET['page'] ) ? sanitize_key( $_GET['page'] ) : '';
- $view = isset( $_GET['view'] ) ? sanitize_key( $_GET['view'] ) : '';
- // phpcs:enable WordPress.Security.NonceVerification.Recommended
-
- return $page === 'wpforms-tools' && $view === 'ai-mcp';
- }
-
- /**
* Enqueue the page JS and localize handler config. Only fires on the AI MCP tab.
*
* @since 1.10.2
*/
public function enqueue_scripts() {
- if ( ! $this->is_ai_mcp_tab() ) {
+ $is_builder = wpforms_is_admin_page( 'builder' );
+ $is_ai_mcp_tab = wpforms_is_admin_page( 'tools', 'ai-mcp' );
+
+ if ( ! $is_builder && ! $is_ai_mcp_tab ) {
return;
}
$min = wpforms_get_min_suffix();
+ // admin-utils.js (the `wpf` global) is registered under different handles per screen:
+ // `wpforms-utils` in the form builder, `wpforms-admin-utils` everywhere else.
+ $utils_handle = $is_builder ? 'wpforms-utils' : 'wpforms-admin-utils';
+
wp_enqueue_script(
'wpforms-ai-mcp',
WPFORMS_PLUGIN_URL . "assets/js/admin/tools/ai-mcp{$min}.js",
- [ 'jquery', 'wpforms-admin-utils' ],
+ [ 'jquery', $utils_handle ],
WPFORMS_VERSION,
true
);
+ // The `wpforms_admin` global is absent in the builder, so the AJAX URL and the
+ // install/activate nonce are passed here instead — keeping one JS path for both screens.
wp_localize_script(
'wpforms-ai-mcp',
'wpformsAiMcpVars',
[
+ 'ajaxUrl' => admin_url( 'admin-ajax.php' ),
+ 'nonce' => wp_create_nonce( 'wpforms-admin' ),
'toggleNonce' => wp_create_nonce( 'wpforms_ai_mcp_toggle' ),
'i18n' => [
'saved' => __( 'Saved', 'wpforms-lite' ),
'genericError' => __( 'Something went wrong. Please try again.', 'wpforms-lite' ),
+ 'confirmSave' => __( 'Your form must be saved before you can go to WPVibe. Save and continue?', 'wpforms-lite' ),
],
]
);
}
/**
+ * Build the shared render args for the AI MCP UI.
+ *
+ * Used by both the Tools → AI MCP tab and the Form Builder settings section so the
+ * promo content, WPVibe state, and write-toggle value stay identical across surfaces.
+ *
+ * @since 1.10.2.1
+ *
+ * @param string $context_class Optional root class that adapts the layout per surface (e.g. the builder variant).
+ *
+ * @return array
+ */
+ public static function get_template_data( string $context_class = '' ): array {
+
+ $user_id = get_current_user_id();
+
+ // The same template renders on Tools → AI MCP and inside the Form Builder; each surface
+ // gets its own UTM medium/content so doc-link clicks are attributed to the right place.
+ $is_builder = $context_class !== '';
+
+ return [
+ 'state' => self::resolve_wpvibe_state(),
+ 'is_write_enabled' => (bool) wpforms_setting( self::SETTING_KEY, false ),
+ 'is_pro' => wpforms()->is_pro(),
+ 'wpvibe_download_url' => self::WPVIBE_DOWNLOAD_URL,
+ 'wpvibe_basename' => self::WPVIBE_BASENAME,
+ 'wpvibe_setup_url' => admin_url( 'admin.php?page=' . self::WPVIBE_PAGE_SLUG ),
+ 'has_visited_wpvibe' => $user_id && (bool) get_user_meta( $user_id, self::USER_META_VISITED_WPVIBE, true ),
+ 'docs_url' => 'https://wpforms.com/docs/using-wpforms-with-ai-assistants/',
+ 'docs_utm_medium' => $is_builder ? 'Builder - AI MCP' : 'Tools - AI MCP',
+ 'docs_utm_content' => $is_builder ? 'View Abilities API Documentation' : 'Learn More - Abilities API Documentation',
+ 'context_class' => $context_class,
+ ];
+ }
+
+ /**
+ * Detect whether WPVibe is not installed, installed but inactive, or active.
+ *
+ * @since 1.10.2.1
+ *
+ * @return string One of 'not_installed', 'installed_inactive', 'active'.
+ */
+ private static function resolve_wpvibe_state(): string {
+
+ if ( ! function_exists( 'is_plugin_active' ) ) {
+ include_once ABSPATH . 'wp-admin/includes/plugin.php';
+ }
+
+ $plugins = get_plugins();
+
+ if ( ! array_key_exists( self::WPVIBE_BASENAME, $plugins ) ) {
+ return 'not_installed';
+ }
+
+ if ( ! is_plugin_active( self::WPVIBE_BASENAME ) ) {
+ return 'installed_inactive';
+ }
+
+ return 'active';
+ }
+
+ /**
* AJAX handler for flipping the write-access toggle.
*
* Validates nonce + admin cap, merges the new value into the shared
--- a/wpforms-lite/templates/admin/tools/ai-mcp.php
+++ b/wpforms-lite/templates/admin/tools/ai-mcp.php
@@ -18,6 +18,9 @@
* @var string $wpvibe_setup_url WPVibe admin page URL — anchor for the active-state CTA.
* @var bool $has_visited_wpvibe True if the user has been on the WPVibe admin page before.
* @var string $docs_url URL for the "View Abilities API Documentation" link.
+ * @var string $docs_utm_medium utm_medium for the docs link, per surface (Tools - AI MCP / Builder - AI MCP).
+ * @var string $docs_utm_content utm_content for the docs link, per surface.
+ * @var string $context_class Optional extra root class to adapt the layout per surface (e.g. the builder variant).
*/
defined( 'ABSPATH' ) || exit;
@@ -75,9 +78,12 @@
'label' => __( 'Cursor', 'wpforms-lite' ),
],
];
+
+// In the builder every WPVibe button state is blue; the Tools page keeps orange for install/activate.
+$wpvibe_button_color = $context_class !== '' ? 'wpforms-btn-blue' : 'wpforms-btn-orange';
?>
-<div class="wpforms-ai-mcp-page">
+<div class="wpforms-ai-mcp-page <?php echo esc_attr( $context_class ); ?>">
<section class="wpforms-ai-mcp-hero">
@@ -114,14 +120,14 @@
<?php if ( $can_install ) : ?>
<button
type="button"
- class="wpforms-btn wpforms-btn-orange wpforms-ai-mcp-wpvibe-button"
+ class="wpforms-btn <?php echo esc_attr( $wpvibe_button_color ); ?> wpforms-ai-mcp-wpvibe-button"
data-action="install"
data-plugin="<?php echo esc_attr( $wpvibe_download_url ); ?>"
><?php esc_html_e( 'Install & Activate WPVibe', 'wpforms-lite' ); ?></button>
<?php else : ?>
<a
href="https://wordpress.org/plugins/vibe-ai/"
- class="wpforms-btn wpforms-btn-orange wpforms-ai-mcp-wpvibe-button"
+ class="wpforms-btn <?php echo esc_attr( $wpvibe_button_color ); ?> wpforms-ai-mcp-wpvibe-button"
target="_blank"
rel="noopener noreferrer"
><?php esc_html_e( 'Install from WordPress.org →', 'wpforms-lite' ); ?></a>
@@ -129,13 +135,13 @@
<?php elseif ( $state === 'installed_inactive' && $can_activate ) : ?>
<button
type="button"
- class="wpforms-btn wpforms-btn-orange wpforms-ai-mcp-wpvibe-button"
+ class="wpforms-btn <?php echo esc_attr( $wpvibe_button_color ); ?> wpforms-ai-mcp-wpvibe-button"
data-action="activate"
data-plugin="<?php echo esc_attr( $wpvibe_basename ); ?>"
><?php esc_html_e( 'Activate WPVibe', 'wpforms-lite' ); ?></button>
<?php elseif ( $state === 'active' ) : ?>
<a
- class="wpforms-btn wpforms-btn-blue wpforms-ai-mcp-wpvibe-button"
+ class="wpforms-btn wpforms-btn-blue wpforms-ai-mcp-wpvibe-button wpforms-ai-mcp-wpvibe-go"
href="<?php echo esc_url( $wpvibe_setup_url ); ?>"
>
<?php
@@ -160,6 +166,13 @@
<label class="wpforms-ai-mcp-toggle-label" for="wpforms-ai-mcp-write-toggle">
<?php esc_html_e( 'Enable MCP Write Access', 'wpforms-lite' ); ?>
</label>
+ <?php if ( $context_class !== '' ) : ?>
+ <i
+ class="fa fa-question-circle-o wpforms-help-tooltip wpforms-ai-mcp-toggle-help"
+ title="<?php esc_attr_e( 'In order for the AI MCP to be able to make changes to your form, Write Access must be enabled.', 'wpforms-lite' ); ?>"
+ aria-hidden="true"
+ ></i>
+ <?php endif; ?>
</span>
</div>
@@ -196,7 +209,7 @@
<h2 class="wpforms-ai-mcp-capabilities-title"><?php esc_html_e( 'Everything WPForms Can Do With AI', 'wpforms-lite' ); ?></h2>
<a
class="wpforms-ai-mcp-docs-link"
- href="<?php echo esc_url( wpforms_utm_link( $docs_url, 'Tools - AI MCP', 'Learn More - Abilities API Documentation' ) ); ?>"
+ href="<?php echo esc_url( wpforms_utm_link( $docs_url, $docs_utm_medium, $docs_utm_content ) ); ?>"
target="_blank"
rel="noopener noreferrer"
>
@@ -211,7 +224,27 @@
<header class="wpforms-ai-mcp-card-head">
<span class="wpforms-ai-mcp-card-icon fa-solid fa-<?php echo esc_attr( $card['icon'] ); ?>" aria-hidden="true"></span>
- <h3 class="wpforms-ai-mcp-card-title"><?php echo esc_html( $card['title'] ); ?></h3>
+ <span class="wpforms-ai-mcp-card-title-group">
+ <h3 class="wpforms-ai-mcp-card-title"><?php echo esc_html( $card['title'] ); ?></h3>
+ <?php if ( $card['pro'] && ! $is_pro ) : ?>
+ <?php
+ // In the builder the badge uses the shared .wpforms-badge system; the Tools page keeps its own styling.
+ $pro_badge_class = 'wpforms-ai-mcp-pro-badge education-modal';
+
+ if ( $context_class !== '' ) {
+ $pro_badge_class = 'wpforms-badge wpforms-badge-sm wpforms-badge-inline wpforms-badge-rounded wpforms-badge-silver ' . $pro_badge_class;
+ }
+ ?>
+ <span
+ class="<?php echo esc_attr( $pro_badge_class ); ?>"
+ data-name="<?php echo esc_attr( $card['title'] ); ?>"
+ data-plural="1"
+ data-action="upgrade"
+ role="button"
+ tabindex="0"
+ ><?php esc_html_e( 'Pro', 'wpforms-lite' ); ?></span>
+ <?php endif; ?>
+ </span>
</header>
<ul class="wpforms-ai-mcp-card-bullets">
@@ -223,17 +256,6 @@
<?php endforeach; ?>
</ul>
- <?php if ( $card['pro'] && ! $is_pro ) : ?>
- <span
- class="wpforms-ai-mcp-pro-badge education-modal"
- data-name="<?php echo esc_attr( $card['title'] ); ?>"
- data-plural="1"
- data-action="upgrade"
- role="button"
- tabindex="0"
- ><?php esc_html_e( 'Pro', 'wpforms-lite' ); ?></span>
- <?php endif; ?>
-
</article>
<?php endforeach; ?>
</div>
--- a/wpforms-lite/vendor/composer/installed.php
+++ b/wpforms-lite/vendor/composer/installed.php
@@ -3,7 +3,7 @@
'name' => 'awesomemotive/wpforms',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
- 'reference' => 'ef22e362092fc86e48c19e16d28b7647900a5446',
+ 'reference' => '7ea46da30343ef729499436bb1666cde9dd058b2',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -49,7 +49,7 @@
'awesomemotive/wpforms' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
- 'reference' => 'ef22e362092fc86e48c19e16d28b7647900a5446',
+ 'reference' => '7ea46da30343ef729499436bb1666cde9dd058b2',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -112,7 +112,7 @@
'roave/security-advisories' => array(
'pretty_version' => 'dev-latest',
'version' => 'dev-latest',
- 'reference' => '6b43b34b35cef5e93f19f389daf029845e391351',
+ 'reference' => '6c54e0520e210e3889b0b3bff4d256bfa19bdc52',
'type' => 'metapackage',
'install_path' => null,
'aliases' => array(
--- a/wpforms-lite/wpforms.php
+++ b/wpforms-lite/wpforms.php
@@ -7,7 +7,7 @@
* Requires PHP: 7.2
* Author: WPForms
* Author URI: https://wpforms.com
- * Version: 1.10.2
+ * Version: 1.10.2.1
* License: GPL v2 or later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: wpforms-lite
@@ -59,7 +59,7 @@
*
* @since 1.0.0
*/
- define( 'WPFORMS_VERSION', '1.10.2' ); // NOSONAR.
+ define( 'WPFORMS_VERSION', '1.10.2.1' ); // NOSONAR.
}
if ( ! defined( 'WPFORMS_PLUGIN_DIR' ) ) {