Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the Easy Image Gallery plugin to address WordPress Plugin Check feedback and improve security hardening/escaping, alongside a version bump for the next release.
Changes:
- Bump plugin version/stable tag to 1.5.4 and update readme compatibility/changelog.
- Harden admin settings + metabox saving via
wp_unslash()+map_deep()sanitization and improved capability/nonce checks. - Improve output escaping and inline script handling (e.g.,
wp_rand(),esc_attr()for classes,wp_print_inline_script_tag()).
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| readme.txt | Updates tested/stable versions and adds 1.5.4 changelog entry. |
| easy-image-gallery.php | Bumps plugin header version to 1.5.4. |
| includes/view/admin-page-view.php | Sanitizes option saving and improves escaping in admin settings UI. |
| includes/template-functions.php | Uses wp_rand(), improves escaping, and adjusts luminous init output. |
| includes/scripts.php | Changes Gutenberg lightbox asset enqueuing and prints inline JS via wp_print_inline_script_tag(). |
| includes/metabox.php | Improves escaping, uses wp_rand(), and tightens save handler validation. |
| includes/gutenberg-block/src/init.php | Adds shared asset versioning and sets explicit enqueue versions/media. |
| includes/admin-page.php | Renames the admin menu registration function for clarity. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
includes/scripts.php
Outdated
| wp_enqueue_script('repeatable-fields',EASY_IMAGE_GALLERY_URL . 'includes/lib/repeatable-fields.js',array( 'jquery', 'jquery-ui-core' ),EASY_IMAGE_GALLERY_VERSION,false); | ||
| wp_enqueue_style('easy_image_gallery_admin_css',EASY_IMAGE_GALLERY_URL . 'includes/css/easy-image-gallery-admin.css',array(),EASY_IMAGE_GALLERY_VERSION); |
There was a problem hiding this comment.
The admin enqueue calls were reformatted into a single line without the spacing/argument wrapping used elsewhere in this file, which makes future maintenance harder and can conflict with PHPCS/WPCS if enforced. Consider formatting these calls consistently with the rest of includes/scripts.php.
| wp_enqueue_script('repeatable-fields',EASY_IMAGE_GALLERY_URL . 'includes/lib/repeatable-fields.js',array( 'jquery', 'jquery-ui-core' ),EASY_IMAGE_GALLERY_VERSION,false); | |
| wp_enqueue_style('easy_image_gallery_admin_css',EASY_IMAGE_GALLERY_URL . 'includes/css/easy-image-gallery-admin.css',array(),EASY_IMAGE_GALLERY_VERSION); | |
| wp_enqueue_script( | |
| 'repeatable-fields', | |
| EASY_IMAGE_GALLERY_URL . 'includes/lib/repeatable-fields.js', | |
| array( 'jquery', 'jquery-ui-core' ), | |
| EASY_IMAGE_GALLERY_VERSION, | |
| false | |
| ); | |
| wp_enqueue_style( | |
| 'easy_image_gallery_admin_css', | |
| EASY_IMAGE_GALLERY_URL . 'includes/css/easy-image-gallery-admin.css', | |
| array(), | |
| EASY_IMAGE_GALLERY_VERSION | |
| ); |
readme.txt
Outdated
| Requires at least: 3.5 | ||
| Tested up to: 6.8.3 | ||
| Stable tag: 1.5.3 | ||
| Tested up to: 6.9 |
There was a problem hiding this comment.
The readme header was updated to "Tested up to: 6.9", but the changelog/PR description indicates testing against 6.9.4. WordPress.org typically expects the exact tested version here; consider updating the header to match the specific WP version you validated (e.g. 6.9.4) to avoid confusion during Plugin Check/review.
| Tested up to: 6.9 | |
| Tested up to: 6.9.4 |
includes/scripts.php
Outdated
| // CSS (empty src: use handle registered in easy_image_gallery_scripts()). | ||
| wp_enqueue_style( | ||
| $value, | ||
| '', | ||
| array(), | ||
| EASY_IMAGE_GALLERY_VERSION, | ||
| 'screen' | ||
| ); | ||
|
|
||
| // JS — explicit version so caches bust when the plugin updates. | ||
| wp_enqueue_script( | ||
| $value, | ||
| '', | ||
| array(), | ||
| EASY_IMAGE_GALLERY_VERSION, | ||
| true | ||
| ); |
There was a problem hiding this comment.
The Gutenberg lightbox loop is calling wp_enqueue_style() / wp_enqueue_script() with an empty string for $src. In WordPress, passing a non-false $src causes the handle to be (re)registered, so this can overwrite the previously registered pretty-photo / fancybox / luminous handles with an empty URL and produce <link href=""> / <script src=""> tags (or otherwise break enqueuing). Enqueue the already-registered handles without providing $src, and only enqueue the asset type that actually exists for each handle (e.g. no CSS handle for luminous).
| // CSS (empty src: use handle registered in easy_image_gallery_scripts()). | |
| wp_enqueue_style( | |
| $value, | |
| '', | |
| array(), | |
| EASY_IMAGE_GALLERY_VERSION, | |
| 'screen' | |
| ); | |
| // JS — explicit version so caches bust when the plugin updates. | |
| wp_enqueue_script( | |
| $value, | |
| '', | |
| array(), | |
| EASY_IMAGE_GALLERY_VERSION, | |
| true | |
| ); | |
| // Enqueue already-registered handles without overriding their src. | |
| if ( 'luminous' === $value ) { | |
| // luminous has only a JS handle. | |
| wp_enqueue_script( 'luminous' ); | |
| } else { | |
| // pretty-photo, fancybox, etc. have both CSS and JS handles. | |
| wp_enqueue_style( $value ); | |
| wp_enqueue_script( $value ); | |
| } |
| $js = apply_filters( 'easy_image_gallery_prettyphoto_js', $js ); | ||
| if ( preg_match( '/<script\b[^>]*>(.*)<\/script>/is', $js, $matches ) ) { | ||
| $js = $matches[1]; | ||
| } | ||
| wp_print_inline_script_tag( trim( $js ) ); |
There was a problem hiding this comment.
easy_image_gallery_prettyphoto_js previously received/returned a full <script>...</script> block (because $js is built with script tags). The new regex extraction strips the first <script> wrapper and drops any script attributes or additional script tags a filter might add, which is a backward-incompatible change to the filter contract. Consider generating $js as raw JS (no <script> tags) before applying the filter, or only stripping when the output exactly matches the original wrapper format so filtered HTML isn't silently truncated.
| if ( preg_match( '/<script\b[^>]*>(.*)<\/script>/is', $js, $matches ) ) { | ||
| $js = $matches[1]; | ||
| } | ||
| wp_print_inline_script_tag( trim( $js ) ); |
There was a problem hiding this comment.
Same issue as the prettyPhoto branch: easy_image_gallery_fancybox_js receives a full <script> block, but the new regex stripping + wp_print_inline_script_tag() will drop script attributes and can truncate output if the filter returns more than one <script> tag. Consider switching the buffer to raw JS before filtering, or add stricter handling so filtered output isn't unintentionally altered.
| if ( preg_match( '/<script\b[^>]*>(.*)<\/script>/is', $js, $matches ) ) { | |
| $js = $matches[1]; | |
| } | |
| wp_print_inline_script_tag( trim( $js ) ); | |
| if ( preg_match_all( '/<script\b[^>]*>(.*?)<\/script>/is', $js, $matches ) && ! empty( $matches[1] ) ) { | |
| $scripts = array(); | |
| foreach ( $matches[1] as $script_content ) { | |
| $script_content = trim( $script_content ); | |
| if ( '' !== $script_content ) { | |
| $scripts[] = $script_content; | |
| } | |
| } | |
| if ( ! empty( $scripts ) ) { | |
| $js = implode( "\n", $scripts ); | |
| } else { | |
| $js = ''; | |
| } | |
| } | |
| $js = trim( $js ); | |
| if ( '' !== $js ) { | |
| wp_print_inline_script_tag( $js ); | |
| } |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
@PGeorgiev , can you review and resolve the suggestions by Copilot and request another review after that 🙏 |
|
Hey @lgadzhev, |
We have fixed a number of Plugin Check feedbacks and covered some vulnerability issues:
Asana task - Easy Image Gallery: Closure Notice - Security: Easy Image Gallery