woocommerce / woocommerce

A customizable, open-source ecommerce platform built on WordPress. Build any commerce solution you can imagine.
https://woocommerce.com
9.3k stars 10.74k forks source link

Over-slashing occurs when editing a review using the REST API #34193

Open jazz-max opened 2 years ago

jazz-max commented 2 years ago

Prerequisites

Describe the bug

I do PUT request to my local wordpress (wp.test) like this

PUT https://wp.test/wp-json/wc/v3/products/reviews/313
Accept: application/json
Content-Type: application/json
Authorization: Basic **********************

{"review":"<p>test\" <img src=image.jpg /></p>"}

Expected behavior

I expect to receive response which should contain the text of the review, for example:

{
  "id": 313,
  ...
  "review": "<p>test\" <img src=image.jpg \/><\/p>",
 ...
}

such a response is returned by the create review method

Or

{
  ...
  "review": "<p>test\" <img src=\"image.jpg\" \/><\/p>",
  ...
}

if wp_filter_post_kses was applied

Actual behavior

But api response

{
  "review": "<p>test\\\" <img src=\\\"image.jpg\\\" \/><\/p>",
}

at the same time, the display of the review gets lost because now its html is already incorrect

Steps to reproduce

  1. Create review with quotes using REST API
  2. Edit review with quotes using REST API

WordPress Environment

`

WordPress Environment

WordPress address (URL): https://wp.test Site address (URL): https://wp.test WC Version: 5.9.1 REST API Version: ✔ 5.9.1 WC Blocks Version: ✔ 6.1.0 Action Scheduler Version: ✔ 3.3.0 WC Admin Version: ✔ 2.8.0 Log Directory Writable: ✔ WP Version: 6.0.1 WP Multisite: – WP Memory Limit: 256 МБ WP Debug Mode: ✔ WP Cron: ✔ Language: ru_RU External object cache: –

Server Environment

Server Info: Apache/2.4.51 (Debian) PHP Version: 7.4.27 PHP Post Max Size: 8 МБ PHP Time Limit: 30 PHP Max Input Vars: 1000 cURL Version: 7.74.0 OpenSSL/1.1.1k

SUHOSIN Installed: – MySQL Version: 8.0.28 Max Upload Size: 8 МБ Default Timezone is UTC: ✔ fsockopen/cURL: ✔ SoapClient: ❌ На вашем сервере не включён класс SoapClient - некоторые плагины шлюзов использующие SOAP могут не работать как ожидалось.

DOMDocument: ✔ GZip: ✔ Multibyte String: ✔ Remote Post: ✔ Remote Get: ✔

Database

WC Database Version: 5.9.1 WC Database Prefix: wp_ Общий размер базы данных: 10.19MB Размер данных в базе данных: 8.09MB Размер индекса базы данных: 2.10MB wp_woocommerce_sessions: Данные: 0.02MB + Индекс: 0.02MB + Движок InnoDB wp_woocommerce_api_keys: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_woocommerce_attribute_taxonomies: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_woocommerce_downloadable_product_permissions: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_woocommerce_order_items: Данные: 0.02MB + Индекс: 0.02MB + Движок InnoDB wp_woocommerce_order_itemmeta: Данные: 0.08MB + Индекс: 0.06MB + Движок InnoDB wp_woocommerce_tax_rates: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_woocommerce_tax_rate_locations: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_woocommerce_shipping_zones: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_woocommerce_shipping_zone_locations: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_woocommerce_shipping_zone_methods: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_woocommerce_payment_tokens: Данные: 0.02MB + Индекс: 0.02MB + Движок InnoDB wp_woocommerce_payment_tokenmeta: Данные: 0.02MB + Индекс: 0.03MB + Движок InnoDB wp_woocommerce_log: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_actionscheduler_actions: Данные: 0.06MB + Индекс: 0.13MB + Движок InnoDB wp_actionscheduler_claims: Данные: 0.02MB + Индекс: 0.02MB + Движок InnoDB wp_actionscheduler_groups: Данные: 0.02MB + Индекс: 0.02MB + Движок InnoDB wp_actionscheduler_logs: Данные: 0.05MB + Индекс: 0.03MB + Движок InnoDB wp_bluesnap_supported_currencies: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_bwf_contact: Данные: 0.02MB + Индекс: 0.06MB + Движок InnoDB wp_bwf_contact_meta: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_bwf_wc_customers: Данные: 0.02MB + Индекс: 0.03MB + Движок InnoDB wp_commentmeta: Данные: 0.02MB + Индекс: 0.03MB + Движок InnoDB wp_comments: Данные: 0.09MB + Индекс: 0.09MB + Движок InnoDB wp_gla_budget_recommendations: Данные: 0.20MB + Индекс: 0.14MB + Движок InnoDB wp_gla_merchant_issues: Данные: 0.02MB + Индекс: 0.02MB + Движок InnoDB wp_gla_shipping_rates: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_gla_shipping_times: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_links: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_mailchimp_carts: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_mailchimp_jobs: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_mailpoet_custom_fields: Данные: 0.02MB + Индекс: 0.02MB + Движок InnoDB wp_mailpoet_dynamic_segment_filters: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_mailpoet_feature_flags: Данные: 0.02MB + Индекс: 0.02MB + Движок InnoDB wp_mailpoet_forms: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_mailpoet_log: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_mailpoet_mapping_to_external_entities: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_mailpoet_newsletter_links: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_mailpoet_newsletter_option: Данные: 0.02MB + Индекс: 0.02MB + Движок InnoDB wp_mailpoet_newsletter_option_fields: Данные: 0.02MB + Индекс: 0.02MB + Движок InnoDB wp_mailpoet_newsletter_posts: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_mailpoet_newsletter_segment: Данные: 0.02MB + Индекс: 0.02MB + Движок InnoDB wp_mailpoet_newsletter_templates: Данные: 2.52MB + Индекс: 0.00MB + Движок InnoDB wp_mailpoet_newsletters: Данные: 0.02MB + Индекс: 0.02MB + Движок InnoDB wp_mailpoet_scheduled_task_subscribers: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_mailpoet_scheduled_tasks: Данные: 0.02MB + Индекс: 0.03MB + Движок InnoDB wp_mailpoet_segments: Данные: 0.02MB + Индекс: 0.03MB + Движок InnoDB wp_mailpoet_sending_queues: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_mailpoet_settings: Данные: 0.02MB + Индекс: 0.02MB + Движок InnoDB wp_mailpoet_statistics_clicks: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_mailpoet_statistics_forms: Данные: 0.02MB + Индекс: 0.02MB + Движок InnoDB wp_mailpoet_statistics_newsletters: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_mailpoet_statistics_opens: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_mailpoet_statistics_unsubscribes: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_mailpoet_statistics_woocommerce_purchases: Данные: 0.02MB + Индекс: 0.02MB + Движок InnoDB wp_mailpoet_stats_notifications: Данные: 0.02MB + Индекс: 0.02MB + Движок InnoDB wp_mailpoet_subscriber_custom_field: Данные: 0.02MB + Индекс: 0.02MB + Движок InnoDB wp_mailpoet_subscriber_ips: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_mailpoet_subscriber_segment: Данные: 0.02MB + Индекс: 0.03MB + Движок InnoDB wp_mailpoet_subscribers: Данные: 0.02MB + Индекс: 0.13MB + Движок InnoDB wp_mailpoet_user_flags: Данные: 0.02MB + Индекс: 0.02MB + Движок InnoDB wp_options: Данные: 3.05MB + Индекс: 0.06MB + Движок InnoDB wp_postmeta: Данные: 0.30MB + Индекс: 0.16MB + Движок InnoDB wp_posts: Данные: 0.09MB + Индекс: 0.06MB + Движок InnoDB wp_term_relationships: Данные: 0.02MB + Индекс: 0.02MB + Движок InnoDB wp_term_taxonomy: Данные: 0.02MB + Индекс: 0.03MB + Движок InnoDB wp_termmeta: Данные: 0.02MB + Индекс: 0.03MB + Движок InnoDB wp_terms: Данные: 0.02MB + Индекс: 0.03MB + Движок InnoDB wp_usermeta: Данные: 0.02MB + Индекс: 0.03MB + Движок InnoDB wp_users: Данные: 0.02MB + Индекс: 0.05MB + Движок InnoDB wp_wc_admin_note_actions: Данные: 0.05MB + Индекс: 0.02MB + Движок InnoDB wp_wc_admin_notes: Данные: 0.06MB + Индекс: 0.00MB + Движок InnoDB wp_wc_category_lookup: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_wc_customer_lookup: Данные: 0.02MB + Индекс: 0.03MB + Движок InnoDB wp_wc_download_log: Данные: 0.02MB + Индекс: 0.03MB + Движок InnoDB wp_wc_order_coupon_lookup: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_wc_order_product_lookup: Данные: 0.02MB + Индекс: 0.06MB + Движок InnoDB wp_wc_order_stats: Данные: 0.02MB + Индекс: 0.05MB + Движок InnoDB wp_wc_order_tax_lookup: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_wc_product_meta_lookup: Данные: 0.02MB + Индекс: 0.09MB + Движок InnoDB wp_wc_reserved_stock: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_wc_tax_rate_classes: Данные: 0.02MB + Индекс: 0.02MB + Движок InnoDB wp_wc_webhooks: Данные: 0.02MB + Индекс: 0.02MB + Движок InnoDB wp_wfco_report_views: Данные: 0.02MB + Индекс: 0.05MB + Движок InnoDB wp_wfocu_event: Данные: 0.02MB + Индекс: 0.05MB + Движок InnoDB wp_wfocu_event_meta: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB wp_wfocu_session: Данные: 0.02MB + Индекс: 0.03MB + Движок InnoDB wp_wpwhpro_authentication: Данные: 0.02MB + Индекс: 0.00MB + Движок InnoDB

Post Type Counts

attachment: 11 mailpoet_page: 1 page: 8 post: 2 product: 4 product_variation: 1 revision: 6 shop_coupon: 1 shop_order: 28 shop_order_refund: 29 wfocu_funnel: 3 wfocu_offer: 3 wp_global_styles: 1

Security

Secure connection (HTTPS): ✔ Hide errors from visitors: ❌Не стоит отображать для посетителей сообщения об ошибках.

Active Plugins (12)

Elementor: от Elementor.com – 3.5.3 Jazz's plugin: от Иван Максимов – 1.3 Jetpack: от Automattic – 10.5 WooFunnels One Click Upsell for Bluesnap: от WooFunnels – 1.3.0 WooCommerce Order Test: от WP Fix It – 1.6 WooCommerce Stripe Gateway: от WooCommerce – 6.2.0 WooCommerce PayPal Payments: от WooCommerce – 1.6.2 (доступно обновление до версии 1.9.1) WooCommerce: от Automattic – 5.9.1 (доступно обновление до версии 6.7.0) UpStroke: WooCommerce One Click Upsells: от buildwoofunnels – 3.2.0 UpStroke PowerPack: от WooFunnels – 1.7.13 WP Webhooks - Comments: от Ironikus – 1.1.0 WP Webhooks: от Ironikus – 3.3.1

Inactive Plugins (3)

BlueSnap Payment Gateway for WooCommerce: от SAU/CAL – 2.5.3 BlueSnap Powered Buy Platform for WooCommerce: от WooThemes – 2.0.16 Hello Dolly: от Matt Mullenweg – 1.7.2

Settings

API Enabled: ✔ Force SSL: ✔ Currency: PLN (zł) Currency Position: left Thousand Separator: Decimal Separator: . Number of Decimals: 2 Taxonomies: Product Types: external (external) grouped (grouped) simple (simple) variable (variable)

Taxonomies: Product Visibility: exclude-from-catalog (exclude-from-catalog) exclude-from-search (exclude-from-search) featured (featured) outofstock (outofstock) rated-1 (rated-1) rated-2 (rated-2) rated-3 (rated-3) rated-4 (rated-4) rated-5 (rated-5)

Connected to WooCommerce.com: –

WC Pages

Ссылка магазина: #6 - /shop/ Корзина: #7 - /cart/ Оформление заказа: #8 - /checkout/ Мой аккаунт: #9 - /my-account/ Правила и условия: ❌ Страница не задана

Theme

Name: Storefront Version: 4.1.0 (доступно обновление до версии 4.1.2) Author URL: https://woocommerce.com/ Child Theme: ❌ – Если вы хотите оформить WooCommerce родительской темой которую создал кто-то другой мы рекомендуем воспользоваться дочерней темой. См. "Как создать дочернюю тему"

WooCommerce Support: ✔

Templates

Overrides: –

WooCommerce PayPal Payments

Onboarded: Yes Shop country code: RU PayPal card processing available in country: No Pay Later messaging available in country: No Vault enabled: Yes

Action Scheduler

Выполнено: 75 Oldest: 2022-07-22 14:38:20 +0000 Newest: 2022-08-04 14:10:19 +0000

В ожидании: 1 Oldest: 2022-08-04 14:10:38 +0000 Newest: 2022-08-04 14:10:38 +0000

Status report information

Generated at: 2022-08-04 17:10:56 +03:00 `

Isolating the problem

jazz-max commented 2 years ago

github strip slashes in my post i try put
{"review":"<p>test\" <img src=image.jpg /></p>"}

and i receive "review": "<p>test\\\" <img src=\\\"image.jpg\\\" \/><\/p>",

its over-slashing

jazz-max commented 2 years ago

I found difference between create and update methods in REST API

\WC_REST_Product_Reviews_Controller::register_routes() register args also with create callback

array(
                    'methods'             => WP_REST_Server::CREATABLE,
                    'callback'            => array( $this, 'create_item' ),
                    'permission_callback' => array( $this, 'create_item_permissions_check' ),
                    'args'                => array_merge(
                        $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array(
                            'product_id'     => array(
                                'required'    => true,
                                'description' => __( 'Unique identifier for the product.', 'woocommerce' ),
                                'type'        => 'integer',
                            ),
                            'review'         => array(
                                'required'    => true,
                                'type'        => 'string',
                                'description' => __( 'Review content.', 'woocommerce' ),
                            ),
                            'reviewer'       => array(
                                'required'    => true,
                                'type'        => 'string',
                                'description' => __( 'Name of the reviewer.', 'woocommerce' ),
                            ),
                            'reviewer_email' => array(
                                'required'    => true,
                                'type'        => 'string',
                                'description' => __( 'Email of the reviewer.', 'woocommerce' ),
                            ),
                        )
                    ),
                ),

but update callback use only 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),

which in turn applies the rest_sanitize_request_arg and wp_filter_post_kses to the body of the review

barryhughes commented 2 years ago

Thank you for the detailed notes, we can reproduce on our end.

It looks like you've already looked into this in a lot of depth—are you interested in submitting a pull request? No worries if not, we'll still get to it, but it occurred you may already have developed your thinking on the best solution.