| @@ -12,8 +12,9 @@ | ||
| 12 | 12 | use WCPOS\WooCommercePOS\Logger; |
| 13 | 13 | use WCPOS\WooCommercePOS\Services\Barcode_Field; |
| 14 | 14 | use WCPOS\WooCommercePOS\Services\Pos_Order_Audit; |
| 15 | 15 | use WCPOS\WooCommercePOS\Services\Settings; |
| 16 | +use WCPOS\WooCommercePOS\Sync\Meta_Normalizer; | |
| 16 | 17 | use WCPOS\WooCommercePOS\Sync\Pos_Uuid; |
| 17 | 18 | use WP_Error; |
| 18 | 19 | use WP_REST_Request; |
| 19 | 20 | use WP_REST_Response; |
| @@ -123,21 +124,36 @@ | ||
| 123 | 124 | * @return array |
| 124 | 125 | */ |
| 125 | 126 | public function wcpos_parse_meta_data( WC_Data $object ): array { |
| 126 | 127 | $raw_meta = $object->get_meta_data(); |
| 127 | - $meta_data = array_map( | |
| 128 | - function ( $meta_data ) { | |
| 129 | - $data = $meta_data->get_data(); | |
| 130 | - return array_merge( | |
| 131 | - $data, | |
| 132 | - array( | |
| 133 | - 'key' => $meta_data->key, | |
| 134 | - 'value' => $meta_data->value, | |
| 135 | - ) | |
| 136 | - ); | |
| 137 | - }, | |
| 138 | - $raw_meta | |
| 139 | - ); | |
| 128 | + $meta_data = array(); | |
| 129 | + $dropped = false; | |
| 130 | + | |
| 131 | + foreach ( $raw_meta as $index => $meta ) { | |
| 132 | + // One monstrous value is what kills the request, and the count monitor below | |
| 133 | + // cannot see it: a record can hold a single meta entry that serializes to a | |
| 134 | + // gigabyte, sail past every threshold on the NUMBER of entries, and then fatal | |
| 135 | + // the response encoder. Measure the value and withhold it, same budget as the | |
| 136 | + // v2 sync lane applies in Meta_Normalizer. | |
| 137 | + if ( Meta_Normalizer::exceeds_value_budget( $meta->value ) ) { | |
| 138 | + Meta_Normalizer::note_oversized_meta( (string) $meta->key, (int) $meta->id ); | |
| 139 | + $dropped = true; | |
| 140 | + continue; | |
| 141 | + } | |
| 142 | + | |
| 143 | + $meta_data[ $index ] = array_merge( | |
| 144 | + $meta->get_data(), | |
| 145 | + array( | |
| 146 | + 'key' => $meta->key, | |
| 147 | + 'value' => $meta->value, | |
| 148 | + ) | |
| 149 | + ); | |
| 150 | + } | |
| 151 | + | |
| 152 | + if ( $dropped ) { | |
| 153 | + // A list with a hole JSON-encodes as an object; the wire expects a list. | |
| 154 | + $meta_data = array_values( $meta_data ); | |
| 155 | + } | |
| 140 | 156 | |
| 141 | 157 | // Monitor meta count and log if thresholds exceeded. |
| 142 | 158 | $this->wcpos_monitor_meta_count( $object, $raw_meta ); |
| 143 | 159 | |