diff options
Diffstat (limited to '')
-rw-r--r-- | netwerk/test/gtest/TestStandardURL.cpp | 441 |
1 files changed, 441 insertions, 0 deletions
diff --git a/netwerk/test/gtest/TestStandardURL.cpp b/netwerk/test/gtest/TestStandardURL.cpp new file mode 100644 index 0000000000..035c92fcc2 --- /dev/null +++ b/netwerk/test/gtest/TestStandardURL.cpp @@ -0,0 +1,441 @@ +#include "gtest/gtest.h" +#include "gtest/MozGTestBench.h" // For MOZ_GTEST_BENCH + +#include "nsCOMPtr.h" +#include "nsNetCID.h" +#include "nsIURL.h" +#include "nsIStandardURL.h" +#include "nsString.h" +#include "nsPrintfCString.h" +#include "nsComponentManagerUtils.h" +#include "nsIURIMutator.h" +#include "mozilla/ipc/URIUtils.h" +#include "mozilla/Unused.h" +#include "nsSerializationHelper.h" +#include "mozilla/Base64.h" +#include "nsEscape.h" + +using namespace mozilla; + +// In nsStandardURL.cpp +extern nsresult Test_NormalizeIPv4(const nsACString& host, nsCString& result); +extern nsresult Test_ParseIPv4Number(const nsACString& input, int32_t base, + uint32_t& number, uint32_t maxNumber); +extern int32_t Test_ValidateIPv4Number(const nsACString& host, int32_t bases[4], + int32_t dotIndex[3], bool& onlyBase10, + int32_t length); +TEST(TestStandardURL, Simple) +{ + nsCOMPtr<nsIURI> url; + ASSERT_EQ(NS_MutateURI(NS_STANDARDURLMUTATOR_CONTRACTID) + .SetSpec("http://example.com"_ns) + .Finalize(url), + NS_OK); + ASSERT_TRUE(url); + + ASSERT_EQ(NS_MutateURI(url).SetSpec("http://example.com"_ns).Finalize(url), + NS_OK); + + nsAutoCString out; + + ASSERT_EQ(url->GetSpec(out), NS_OK); + ASSERT_TRUE(out == "http://example.com/"_ns); + + ASSERT_EQ(url->Resolve("foo.html?q=45"_ns, out), NS_OK); + ASSERT_TRUE(out == "http://example.com/foo.html?q=45"_ns); + + ASSERT_EQ(NS_MutateURI(url).SetScheme("foo"_ns).Finalize(url), NS_OK); + + ASSERT_EQ(url->GetScheme(out), NS_OK); + ASSERT_TRUE(out == "foo"_ns); + + ASSERT_EQ(url->GetHost(out), NS_OK); + ASSERT_TRUE(out == "example.com"_ns); + ASSERT_EQ(NS_MutateURI(url).SetHost("www.yahoo.com"_ns).Finalize(url), NS_OK); + ASSERT_EQ(url->GetHost(out), NS_OK); + ASSERT_TRUE(out == "www.yahoo.com"_ns); + + ASSERT_EQ(NS_MutateURI(url) + .SetPathQueryRef(nsLiteralCString( + "/some-path/one-the-net/about.html?with-a-query#for-you")) + .Finalize(url), + NS_OK); + ASSERT_EQ(url->GetPathQueryRef(out), NS_OK); + ASSERT_TRUE(out == + nsLiteralCString( + "/some-path/one-the-net/about.html?with-a-query#for-you")); + + ASSERT_EQ(NS_MutateURI(url) + .SetQuery(nsLiteralCString( + "a=b&d=c&what-ever-you-want-to-be-called=45")) + .Finalize(url), + NS_OK); + ASSERT_EQ(url->GetQuery(out), NS_OK); + ASSERT_TRUE(out == "a=b&d=c&what-ever-you-want-to-be-called=45"_ns); + + ASSERT_EQ(NS_MutateURI(url).SetRef("#some-book-mark"_ns).Finalize(url), + NS_OK); + ASSERT_EQ(url->GetRef(out), NS_OK); + ASSERT_TRUE(out == "some-book-mark"_ns); +} + +TEST(TestStandardURL, NormalizeGood) +{ + nsCString result; + const char* manual[] = {"0.0.0.0", + "0.0.0.0", + "0", + "0.0.0.0", + "000", + "0.0.0.0", + "0x00", + "0.0.0.0", + "10.20.100.200", + "10.20.100.200", + "255.255.255.255", + "255.255.255.255", + "0XFF.0xFF.0xff.0xFf", + "255.255.255.255", + "0x000ff.0X00FF.0x0ff.0xff", + "255.255.255.255", + "0x000fA.0X00FB.0x0fC.0xfD", + "250.251.252.253", + "0x000fE.0X00FF.0x0fC.0xfD", + "254.255.252.253", + "0x000fa.0x00fb.0x0fc.0xfd", + "250.251.252.253", + "0x000fe.0x00ff.0x0fc.0xfd", + "254.255.252.253", + "0377.0377.0377.0377", + "255.255.255.255", + "0000377.000377.00377.0377", + "255.255.255.255", + "65535", + "0.0.255.255", + "0xfFFf", + "0.0.255.255", + "0x00000ffff", + "0.0.255.255", + "0177777", + "0.0.255.255", + "000177777", + "0.0.255.255", + "0.13.65535", + "0.13.255.255", + "0.22.0xffff", + "0.22.255.255", + "0.123.0177777", + "0.123.255.255", + "65536", + "0.1.0.0", + "0200000", + "0.1.0.0", + "0x10000", + "0.1.0.0"}; + for (uint32_t i = 0; i < sizeof(manual) / sizeof(manual[0]); i += 2) { + nsCString encHost(manual[i + 0]); + ASSERT_EQ(NS_OK, Test_NormalizeIPv4(encHost, result)); + ASSERT_TRUE(result.Equals(manual[i + 1])); + } + + // Make sure we're getting the numbers correctly interpreted: + for (int i = 0; i < 256; i++) { + nsCString encHost = nsPrintfCString("0x%x", i); + ASSERT_EQ(NS_OK, Test_NormalizeIPv4(encHost, result)); + ASSERT_TRUE(result.Equals(nsPrintfCString("0.0.0.%d", i))); + + encHost = nsPrintfCString("0%o", i); + ASSERT_EQ(NS_OK, Test_NormalizeIPv4(encHost, result)); + ASSERT_TRUE(result.Equals(nsPrintfCString("0.0.0.%d", i))); + } + + // Some random numbers in the range, mixing hex, decimal, octal + for (int i = 0; i < 8; i++) { + int val[4] = {i * 11 + 13, i * 18 + 22, i * 4 + 28, i * 15 + 2}; + + nsCString encHost = + nsPrintfCString("%d.%d.%d.%d", val[0], val[1], val[2], val[3]); + ASSERT_EQ(NS_OK, Test_NormalizeIPv4(encHost, result)); + ASSERT_TRUE(result.Equals(encHost)); + + nsCString encHostM = + nsPrintfCString("0x%x.0x%x.0x%x.0x%x", val[0], val[1], val[2], val[3]); + ASSERT_EQ(NS_OK, Test_NormalizeIPv4(encHostM, result)); + ASSERT_TRUE(result.Equals(encHost)); + + encHostM = + nsPrintfCString("0%o.0%o.0%o.0%o", val[0], val[1], val[2], val[3]); + ASSERT_EQ(NS_OK, Test_NormalizeIPv4(encHostM, result)); + ASSERT_TRUE(result.Equals(encHost)); + + encHostM = + nsPrintfCString("0x%x.%d.0%o.%d", val[0], val[1], val[2], val[3]); + ASSERT_EQ(NS_OK, Test_NormalizeIPv4(encHostM, result)); + ASSERT_TRUE(result.Equals(encHost)); + + encHostM = + nsPrintfCString("%d.0%o.0%o.0x%x", val[0], val[1], val[2], val[3]); + ASSERT_EQ(NS_OK, Test_NormalizeIPv4(encHostM, result)); + ASSERT_TRUE(result.Equals(encHost)); + + encHostM = + nsPrintfCString("0%o.0%o.0x%x.0x%x", val[0], val[1], val[2], val[3]); + ASSERT_EQ(NS_OK, Test_NormalizeIPv4(encHostM, result)); + ASSERT_TRUE(result.Equals(encHost)); + } +} + +TEST(TestStandardURL, NormalizeBad) +{ + nsAutoCString result; + const char* manual[] = { + "x22.232.12.32", "122..12.32", "122.12.32.12.32", "122.12.32..", + "122.12.xx.22", "122.12.0xx.22", "0xx.12.01.22", "12.12.02x.22", + "1q.12.2.22", "122.01f.02.22", "12a.01.02.22", "12.01.02.20x1", + "10x2.01.02.20", "0xx.01.02.20", "10.x.02.20", "10.00x2.02.20", + "10.13.02x2.20", "10.x13.02.20", "10.0x134def.02.20", "\0.2.2.2", + "256.2.2.2", "2.256.2.2", "2.2.256.2", "2.2.2.256", + "2.2.-2.3", "+2.2.2.3", "13.0x2x2.2.3", "0x2x2.13.2.3"}; + + for (auto& i : manual) { + nsCString encHost(i); + ASSERT_EQ(NS_ERROR_FAILURE, Test_NormalizeIPv4(encHost, result)); + } +} + +TEST(TestStandardURL, From_test_standardurldotjs) +{ + // These are test (success and failure) cases from test_standardurl.js + nsAutoCString result; + + const char* localIPv4s[] = { + "127.0.0.1", + "127.0.1", + "127.1", + "2130706433", + "0177.00.00.01", + "0177.00.01", + "0177.01", + "00000000000000000000000000177.0000000.0000000.0001", + "000000177.0000001", + "017700000001", + "0x7f.0x00.0x00.0x01", + "0x7f.0x01", + "0x7f000001", + "0x007f.0x0000.0x0000.0x0001", + "000177.0.00000.0x0001", + "127.0.0.1.", + + "0X7F.0X00.0X00.0X01", + "0X7F.0X01", + "0X7F000001", + "0X007F.0X0000.0X0000.0X0001", + "000177.0.00000.0X0001"}; + for (auto& localIPv4 : localIPv4s) { + nsCString encHost(localIPv4); + ASSERT_EQ(NS_OK, Test_NormalizeIPv4(encHost, result)); + ASSERT_TRUE(result.EqualsLiteral("127.0.0.1")); + } + + const char* nonIPv4s[] = {"0xfffffffff", "0x100000000", + "4294967296", "1.2.0x10000", + "1.0x1000000", "256.0.0.1", + "1.256.1", "-1.0.0.0", + "1.2.3.4.5", "010000000000000000", + "2+3", "0.0.0.-1", + "1.2.3.4..", "1..2", + ".1.2.3.4", ".127"}; + for (auto& nonIPv4 : nonIPv4s) { + nsCString encHost(nonIPv4); + ASSERT_EQ(NS_ERROR_FAILURE, Test_NormalizeIPv4(encHost, result)); + } + + const char* oneOrNoDotsIPv4s[] = {"127", "127."}; + for (auto& localIPv4 : oneOrNoDotsIPv4s) { + nsCString encHost(localIPv4); + ASSERT_EQ(NS_OK, Test_NormalizeIPv4(encHost, result)); + ASSERT_TRUE(result.EqualsLiteral("0.0.0.127")); + } +} + +#define TEST_COUNT 10000 + +MOZ_GTEST_BENCH(TestStandardURL, DISABLED_Perf, [] { + nsCOMPtr<nsIURI> url; + ASSERT_EQ(NS_OK, NS_MutateURI(NS_STANDARDURLMUTATOR_CONTRACTID) + .SetSpec("http://example.com"_ns) + .Finalize(url)); + + nsAutoCString out; + for (int i = TEST_COUNT; i; --i) { + ASSERT_EQ(NS_MutateURI(url).SetSpec("http://example.com"_ns).Finalize(url), + NS_OK); + ASSERT_EQ(url->GetSpec(out), NS_OK); + url->Resolve("foo.html?q=45"_ns, out); + mozilla::Unused << NS_MutateURI(url).SetScheme("foo"_ns).Finalize(url); + url->GetScheme(out); + mozilla::Unused + << NS_MutateURI(url).SetHost("www.yahoo.com"_ns).Finalize(url); + url->GetHost(out); + mozilla::Unused + << NS_MutateURI(url) + .SetPathQueryRef(nsLiteralCString( + "/some-path/one-the-net/about.html?with-a-query#for-you")) + .Finalize(url); + url->GetPathQueryRef(out); + mozilla::Unused << NS_MutateURI(url) + .SetQuery(nsLiteralCString( + "a=b&d=c&what-ever-you-want-to-be-called=45")) + .Finalize(url); + url->GetQuery(out); + mozilla::Unused + << NS_MutateURI(url).SetRef("#some-book-mark"_ns).Finalize(url); + url->GetRef(out); + } +}); + +// Note the five calls in the loop, so divide by 100k +MOZ_GTEST_BENCH(TestStandardURL, DISABLED_NormalizePerf, [] { + nsAutoCString result; + for (int i = 0; i < 20000; i++) { + nsAutoCString encHost("123.232.12.32"); + ASSERT_EQ(NS_OK, Test_NormalizeIPv4(encHost, result)); + nsAutoCString encHost2("83.62.12.92"); + ASSERT_EQ(NS_OK, Test_NormalizeIPv4(encHost2, result)); + nsAutoCString encHost3("8.7.6.5"); + ASSERT_EQ(NS_OK, Test_NormalizeIPv4(encHost3, result)); + nsAutoCString encHost4("111.159.123.220"); + ASSERT_EQ(NS_OK, Test_NormalizeIPv4(encHost4, result)); + nsAutoCString encHost5("1.160.204.200"); + ASSERT_EQ(NS_OK, Test_NormalizeIPv4(encHost5, result)); + } +}); + +// Bug 1394785 - ignore unstable test on OSX +#ifndef XP_MACOSX +// Note the five calls in the loop, so divide by 100k +MOZ_GTEST_BENCH(TestStandardURL, DISABLED_NormalizePerfFails, [] { + nsAutoCString result; + for (int i = 0; i < 20000; i++) { + nsAutoCString encHost("123.292.12.32"); + ASSERT_EQ(NS_ERROR_FAILURE, Test_NormalizeIPv4(encHost, result)); + nsAutoCString encHost2("83.62.12.0x13292"); + ASSERT_EQ(NS_ERROR_FAILURE, Test_NormalizeIPv4(encHost2, result)); + nsAutoCString encHost3("8.7.6.0xhello"); + ASSERT_EQ(NS_ERROR_FAILURE, Test_NormalizeIPv4(encHost3, result)); + nsAutoCString encHost4("111.159.notonmywatch.220"); + ASSERT_EQ(NS_ERROR_FAILURE, Test_NormalizeIPv4(encHost4, result)); + nsAutoCString encHost5("1.160.204.20f"); + ASSERT_EQ(NS_ERROR_FAILURE, Test_NormalizeIPv4(encHost5, result)); + } +}); +#endif + +TEST(TestStandardURL, Mutator) +{ + nsAutoCString out; + nsCOMPtr<nsIURI> uri; + nsresult rv = NS_MutateURI(NS_STANDARDURLMUTATOR_CONTRACTID) + .SetSpec("http://example.com"_ns) + .Finalize(uri); + ASSERT_EQ(rv, NS_OK); + + ASSERT_EQ(uri->GetSpec(out), NS_OK); + ASSERT_TRUE(out == "http://example.com/"_ns); + + rv = NS_MutateURI(uri) + .SetScheme("ftp"_ns) + .SetHost("mozilla.org"_ns) + .SetPathQueryRef("/path?query#ref"_ns) + .Finalize(uri); + ASSERT_EQ(rv, NS_OK); + ASSERT_EQ(uri->GetSpec(out), NS_OK); + ASSERT_TRUE(out == "ftp://mozilla.org/path?query#ref"_ns); + + nsCOMPtr<nsIURL> url; + rv = NS_MutateURI(uri).SetScheme("https"_ns).Finalize(url); + ASSERT_EQ(rv, NS_OK); + ASSERT_EQ(url->GetSpec(out), NS_OK); + ASSERT_TRUE(out == "https://mozilla.org/path?query#ref"_ns); +} + +TEST(TestStandardURL, Deserialize_Bug1392739) +{ + mozilla::ipc::StandardURLParams standard_params; + standard_params.urlType() = nsIStandardURL::URLTYPE_STANDARD; + standard_params.spec().Truncate(); + standard_params.host() = mozilla::ipc::StandardURLSegment(4294967295, 1); + + mozilla::ipc::URIParams params(standard_params); + + nsCOMPtr<nsIURIMutator> mutator = + do_CreateInstance(NS_STANDARDURLMUTATOR_CID); + ASSERT_EQ(mutator->Deserialize(params), NS_ERROR_FAILURE); +} + +TEST(TestStandardURL, CorruptSerialization) +{ + auto spec = "http://user:pass@example.com/path/to/file.ext?query#hash"_ns; + + nsCOMPtr<nsIURI> uri; + nsresult rv = NS_MutateURI(NS_STANDARDURLMUTATOR_CONTRACTID) + .SetSpec(spec) + .Finalize(uri); + ASSERT_EQ(rv, NS_OK); + + nsAutoCString serialization; + nsCOMPtr<nsISerializable> serializable = do_QueryInterface(uri); + ASSERT_TRUE(serializable); + + // Check that the URL is normally serializable. + ASSERT_EQ(NS_OK, NS_SerializeToString(serializable, serialization)); + nsCOMPtr<nsISupports> deserializedObject; + ASSERT_EQ(NS_OK, NS_DeserializeObject(serialization, + getter_AddRefs(deserializedObject))); + + nsAutoCString canonicalBin; + Unused << Base64Decode(serialization, canonicalBin); + +// The spec serialization begins at byte 49 +// If the implementation of nsStandardURL::Write changes, this test will need +// to be adjusted. +#define SPEC_OFFSET 49 + + ASSERT_EQ(Substring(canonicalBin, SPEC_OFFSET, 7), "http://"_ns); + + nsAutoCString corruptedBin = canonicalBin; + // change mScheme.mPos + corruptedBin.BeginWriting()[SPEC_OFFSET + spec.Length()] = 1; + Unused << Base64Encode(corruptedBin, serialization); + ASSERT_EQ( + NS_ERROR_MALFORMED_URI, + NS_DeserializeObject(serialization, getter_AddRefs(deserializedObject))); + + corruptedBin = canonicalBin; + // change mScheme.mLen + corruptedBin.BeginWriting()[SPEC_OFFSET + spec.Length() + 4] = 127; + Unused << Base64Encode(corruptedBin, serialization); + ASSERT_EQ( + NS_ERROR_MALFORMED_URI, + NS_DeserializeObject(serialization, getter_AddRefs(deserializedObject))); +} + +TEST(TestStandardURL, ParseIPv4Num) +{ + auto host = "0x.0x.0"_ns; + + int32_t bases[4] = {10, 10, 10, 10}; + bool onlyBase10 = true; // Track this as a special case + int32_t dotIndex[3]; // The positions of the dots in the string + int32_t length = static_cast<int32_t>(host.Length()); + + ASSERT_EQ(2, + Test_ValidateIPv4Number(host, bases, dotIndex, onlyBase10, length)); + + nsCString result; + ASSERT_EQ(NS_OK, Test_NormalizeIPv4("0x.0x.0"_ns, result)); + + uint32_t number; + Test_ParseIPv4Number("0x10"_ns, 16, number, 255); + ASSERT_EQ(number, (uint32_t)16); +} |