From f9c20132ad38c7152e5faa4a1e9ee9ead5b71fb8 Mon Sep 17 00:00:00 2001 From: Jan Henning Thorsen Date: Thu, 17 Jun 2021 10:36:13 +0900 Subject: [PATCH] Fix validating multipart\/form-data with boundary --- Changes | 1 + lib/JSON/Validator/Util.pm | 9 ++++++--- t/util.t | 4 +++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Changes b/Changes index fe1f351d..21ed3c6a 100644 --- a/Changes +++ b/Changes @@ -2,6 +2,7 @@ Revision history for perl distribution JSON-Validator 4.18 Not Released - Fix content_type validation for OpenAPIv2 and OpenAPIv3 + - Fix validating multipart\/form-data with boundary 4.17 2021-04-28T11:30:56+0900 - Add add_default_response() to OpenAPIv2 and OpenAPIv3 diff --git a/lib/JSON/Validator/Util.pm b/lib/JSON/Validator/Util.pm index 3311996e..ca593d91 100644 --- a/lib/JSON/Validator/Util.pm +++ b/lib/JSON/Validator/Util.pm @@ -90,13 +90,16 @@ sub negotiate_content_type { my ($accepts, $header) = @_; return '' unless $header; - my %header_map; - /^\s*([^,; ]+)(?:\s*\;\s*q\s*=\s*(\d+(?:\.\d+)?))?\s*$/i and $header_map{lc $1} = $2 // 1 for split /,/, $header; + my %header_map = map { + /^\s*([^,; ]+)(?:\s*\;\s*q\s*=\s*(\d+(?:\.\d+)?))?\s*$/i ? (lc $1, $2) + : /^\s*([^,; ]+)(?:\s*\;\s*\w+\s*=\S+)?\s*$/i ? (lc $1, -1) + : (lc $_, -2); + } split /,/, $header; my @headers = sort { $header_map{$b} <=> $header_map{$a} } sort keys %header_map; # Check for exact match for my $ct (@$accepts) { - return $ct if $header_map{$ct}; + return $ct if exists $header_map{$ct}; } # Check for closest match diff --git a/t/util.t b/t/util.t index 6181c9d4..1609d1ea 100644 --- a/t/util.t +++ b/t/util.t @@ -42,9 +42,11 @@ is_deeply( ); is negotiate_content_type([]), '', 'accepts nothing'; +is negotiate_content_type(['multipart/form-data'], 'multipart/form-data; boundary=mgkBX'), 'multipart/form-data', + 'form-data boundary'; is negotiate_content_type(['application/json']), '', 'header missing'; is negotiate_content_type(['application/json', 'text/plain'], 'application/json'), 'application/json', 'exact match'; -is negotiate_content_type(['application/json', 'text/*'], 'text/plain'), 'text/*', 'closest accept'; +is negotiate_content_type(['application/json', 'text/*'], 'text/plain'), 'text/*', 'closest accept'; is negotiate_content_type( ['text/plain', 'application/xml'], 'text/html;text/plain;q=0.2,application/xml;q=0.9,*/*;q=0.8'