diff --git a/sgx-bwmsgsv2.rb b/sgx-bwmsgsv2.rb index c706d248ef86a4a89538f1843b90425c31dccaa0..c2cc46007dab43847426cdf4ea6d9db96d0aa49a 100755 --- a/sgx-bwmsgsv2.rb +++ b/sgx-bwmsgsv2.rb @@ -446,6 +446,14 @@ module SGXbwmsgsv2 ]) end + if body =~ /\u2063/ + return EMPromise.reject([ + :wait, + 'recipient-unavailable', + 'Please contact JMP support about your message' + ]) + end + segment_size = body.ascii_only? ? 160 : 70 if !murl && ENV["MMS_PATH"] && body.length > segment_size*3 file = Multibases.pack( diff --git a/test/property/test_invisible_separator.rb b/test/property/test_invisible_separator.rb new file mode 100644 index 0000000000000000000000000000000000000000..e3994d056e1b2bd37402cf1688846ebf1f607691 --- /dev/null +++ b/test/property/test_invisible_separator.rb @@ -0,0 +1,91 @@ +# frozen_string_literal: true + +require "test_helper" +require_relative "../../sgx-bwmsgsv2" +require "rantly/minitest_extensions" +require_relative "rantly_extensions/data_extensions" + +class InvisibleSeparatorPropertyTest < Minitest::Test + BW_MESSAGES_URL = + "https://messaging.bandwidth.com/api/v2/users/account/messages" + + def setup + reset_stanzas! + reset_redis! + end + + def test_message_containing_invisible_separator_is_rejected + property_of { + words = array(range(1, 6)) { sized(range(3, 10)) { string(:alnum) } } + guard(words.none? { |w| BADWORD_LIST.include?(w.downcase) }) + chars = words.join(" ").chars + insertions = range(1, 3) + insertions.times { chars.insert(range(0, chars.length), "\u2063") } + body = chars.join + + dest = nanpa_phone + [body, dest] + }.check { |body, dest| + reset_stanzas! + reset_redis! + + stub_request(:post, BW_MESSAGES_URL).to_return( + status: 201, + body: JSON.dump(id: "bw-msg-stub") + ) + + m = Blather::Stanza::Message.new("#{dest}@component", body) + m.from = "test@example.com" + process_stanza(m) + + assert_equal 1, written.length, + "Expected exactly one error stanza for body: #{body.inspect}" + + stanza = Blather::XMPPNode.parse(written.first.to_xml) + assert stanza.error?, + "Expected error stanza for body: #{body.inspect}" + + error = stanza.find_first("error") + assert_equal "wait", error["type"], + "Expected error type 'wait' for body: #{body.inspect}" + assert_equal "recipient-unavailable", xmpp_error_name(error), + "Expected 'recipient-unavailable' for body: #{body.inspect}" + } + end + em :test_message_containing_invisible_separator_is_rejected + + def test_message_without_invisible_separator_is_not_rejected_as_unavailable + property_of { + words = array(range(1, 6)) { sized(range(3, 10)) { string(:alnum) } } + guard(words.none? { |w| BADWORD_LIST.include?(w.downcase) }) + body = words.join(" ") + + dest = nanpa_phone + [body, dest] + }.check { |body, dest| + reset_stanzas! + reset_redis! + + stub_request(:post, BW_MESSAGES_URL).to_return( + status: 201, + body: JSON.dump(id: "bw-msg-stub") + ) + + m = Blather::Stanza::Message.new("#{dest}@component", body) + m.from = "test@example.com" + process_stanza(m) + + written.each do |response| + stanza = Blather::XMPPNode.parse(response.to_xml) + next unless stanza.error? + + error = stanza.find_first("error") + msg = "Clean message rejected as " \ + "recipient-unavailable: #{body.inspect}" + refute_equal "recipient-unavailable", + xmpp_error_name(error), msg + end + } + end + em :test_message_without_invisible_separator_is_not_rejected_as_unavailable +end