Bug 1620769 - Convert net_IsValidScheme function to Rust r=valentin
authorundef1nd <yalyna.ts@gmail.com>
Sun, 15 Mar 2020 12:09:57 +0000
changeset 518816 429fb5cee0650c3e72e12c1865ca4b4cb1f80072
parent 518815 e48c6fefd0afb20daeb6056aba0c42654b0b362f
child 518817 eda75d901f4c6bbd902ec4a887865a3382287704
push id37217
push userccoroiu@mozilla.com
push dateSun, 15 Mar 2020 21:37:59 +0000
treeherdermozilla-central@f9fc9427476e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvalentin
bugs1620769
milestone76.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1620769 - Convert net_IsValidScheme function to Rust r=valentin Differential Revision: https://phabricator.services.mozilla.com/D66871
netwerk/base/nsURLHelper.cpp
netwerk/base/nsURLHelper.h
netwerk/base/nsURLParsers.cpp
netwerk/base/rust-helper/src/helper.h
netwerk/base/rust-helper/src/lib.rs
--- a/netwerk/base/nsURLHelper.cpp
+++ b/netwerk/base/nsURLHelper.cpp
@@ -448,28 +448,18 @@ nsresult net_ExtractURLScheme(const nsAC
   }
 
   p.Claim(scheme);
   scheme.StripTaggedASCII(ASCIIMask::MaskCRLFTab());
   ToLowerCase(scheme);
   return NS_OK;
 }
 
-bool net_IsValidScheme(const char* scheme, uint32_t schemeLen) {
-  // first char must be alpha
-  if (!IsAsciiAlpha(*scheme)) return false;
-
-  // nsCStrings may have embedded nulls -- reject those too
-  for (; schemeLen; ++scheme, --schemeLen) {
-    if (!(IsAsciiAlpha(*scheme) || IsAsciiDigit(*scheme) || *scheme == '+' ||
-          *scheme == '.' || *scheme == '-'))
-      return false;
-  }
-
-  return true;
+bool net_IsValidScheme(const nsACString& scheme) {
+  return rust_net_is_valid_scheme(scheme);
 }
 
 bool net_IsAbsoluteURL(const nsACString& uri) {
   nsACString::const_iterator start, end;
   uri.BeginReading(start);
   uri.EndReading(end);
 
   // Strip C0 and space from begining
--- a/netwerk/base/nsURLHelper.h
+++ b/netwerk/base/nsURLHelper.h
@@ -89,21 +89,17 @@ bool net_IsAbsoluteURL(const nsACString&
  * Extract URI-Scheme if possible
  *
  * @param inURI     URI spec
  * @param scheme    scheme copied to this buffer on return. Is lowercase.
  */
 nsresult net_ExtractURLScheme(const nsACString& inURI, nsACString& scheme);
 
 /* check that the given scheme conforms to RFC 2396 */
-bool net_IsValidScheme(const char* scheme, uint32_t schemeLen);
-
-inline bool net_IsValidScheme(const nsCString& scheme) {
-  return net_IsValidScheme(scheme.get(), scheme.Length());
-}
+bool net_IsValidScheme(const nsACString& scheme);
 
 /**
  * This function strips out all C0 controls and space at the beginning and end
  * of the URL and filters out \r, \n, \t from the middle of the URL.  This makes
  * it safe to call on things like javascript: urls or data: urls, where we may
  * in fact run into whitespace that is not properly encoded.
  *
  * @param input the URL spec we want to filter
--- a/netwerk/base/nsURLParsers.cpp
+++ b/netwerk/base/nsURLParsers.cpp
@@ -107,17 +107,18 @@ nsBaseURLParser::ParseURL(const char* sp
     //
     // spec = <scheme>:/<the-rest>
     //
     // or
     //
     // spec = <scheme>:<authority>
     // spec = <scheme>:<path-no-slashes>
     //
-    if (!net_IsValidScheme(spec, colon - spec) || (*(colon + 1) == ':')) {
+    if (!net_IsValidScheme(nsDependentCSubstring(spec, colon - spec)) ||
+        (*(colon + 1) == ':')) {
       return NS_ERROR_MALFORMED_URI;
     }
     SET_RESULT(scheme, offset, colon - spec);
     if (authorityLen || pathLen) {
       uint32_t schemeLen = colon + 1 - spec;
       offset += schemeLen;
       ParseAfterScheme(colon + 1, specLen - schemeLen, authorityPos,
                        authorityLen, pathPos, pathLen);
--- a/netwerk/base/rust-helper/src/helper.h
+++ b/netwerk/base/rust-helper/src/helper.h
@@ -15,11 +15,13 @@ extern "C" {
 nsresult rust_prepare_accept_languages(const nsACString* i_accept_languages,
                                        nsACString* o_accept_languages);
 
 bool rust_net_is_valid_ipv4_addr(const nsACString& aAddr);
 
 bool rust_net_is_valid_ipv6_addr(const nsACString& aAddr);
 
 bool rust_net_is_valid_scheme_char(const char aChar);
+
+bool rust_net_is_valid_scheme(const nsACString& scheme);
 }
 
 #endif  // RUST_NS_NET_HELPER
--- a/netwerk/base/rust-helper/src/lib.rs
+++ b/netwerk/base/rust-helper/src/lib.rs
@@ -281,11 +281,31 @@ pub fn is_valid_ipv6_addr<'a>(addr: &'a 
     }
 
     double_colon && blocks < 8 || !double_colon && blocks == 8
 }
 
 #[no_mangle]
 #[allow(non_snake_case)]
 pub extern "C" fn rust_net_is_valid_scheme_char(a_char: u8) -> bool {
-    let a_char = a_char as char;
-    a_char.is_ascii_alphanumeric() || a_char == '+' || a_char == '.' || a_char == '-'
+    is_valid_scheme_char(a_char)
 }
+
+#[no_mangle]
+#[allow(non_snake_case)]
+pub extern "C" fn rust_net_is_valid_scheme<'a>(scheme: &'a nsACString) -> bool {
+    if scheme.is_empty() {
+        return false;
+    }
+
+    // first char must be alpha
+    if !scheme[0].is_ascii_alphabetic() {
+        return false;
+    }
+
+    scheme[1..]
+        .iter()
+        .all(|a_char| is_valid_scheme_char(*a_char))
+}
+
+fn is_valid_scheme_char(a_char: u8) -> bool {
+    a_char.is_ascii_alphanumeric() || a_char == b'+' || a_char == b'.' || a_char == b'-'
+}