From d31ed25422f0c900e8f3ed081d384052bdd13c32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Gili?= Date: Mon, 15 Jul 2024 19:13:06 +0200 Subject: [PATCH] Fix exception when soap:Fault contains invalid encoding (#923) Co-authored-by: David Escala --- lib/savon/soap_fault.rb | 9 ++++++++- spec/fixtures/response/soap_fault_invalid_encoding.xml | 8 ++++++++ spec/savon/soap_fault_spec.rb | 5 +++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 spec/fixtures/response/soap_fault_invalid_encoding.xml diff --git a/lib/savon/soap_fault.rb b/lib/savon/soap_fault.rb index 40e61dfc..9cf93939 100644 --- a/lib/savon/soap_fault.rb +++ b/lib/savon/soap_fault.rb @@ -3,7 +3,14 @@ module Savon class SOAPFault < Error def self.present?(http, xml = nil) - xml ||= http.body + xml_orig ||= http.body + if xml_orig.valid_encoding? + xml = xml_orig + else + xml = xml_orig.encode( + 'UTF-8', "ISO-8859-1", invalid: :replace, undef: :replace, replace: '' + ) + end fault_node = xml.include?("Fault>") soap1_fault = xml.match(/faultcode\/?>/) && xml.match(/faultstring\/?>/) soap2_fault = xml.include?("Code>") && xml.include?("Reason>") diff --git a/spec/fixtures/response/soap_fault_invalid_encoding.xml b/spec/fixtures/response/soap_fault_invalid_encoding.xml new file mode 100644 index 00000000..5bf26524 --- /dev/null +++ b/spec/fixtures/response/soap_fault_invalid_encoding.xml @@ -0,0 +1,8 @@ + + + + soap:Server + Response with invalid encoding ñ ñ + + + diff --git a/spec/savon/soap_fault_spec.rb b/spec/savon/soap_fault_spec.rb index 6e38dbe0..b14e9b09 100644 --- a/spec/savon/soap_fault_spec.rb +++ b/spec/savon/soap_fault_spec.rb @@ -49,6 +49,11 @@ it "returns false unless the HTTP response contains a SOAP fault" do expect(Savon::SOAPFault.present? new_response).to be_falsey end + + it "returns true if the HTTP response contains a SOAP fault with invalid ecoded char" do + http = new_response(:body => Fixture.response(:soap_fault_invalid_encoding)) + expect(Savon::SOAPFault.present? http).to be_truthy + end end [:message, :to_s].each do |method|