types/src/main/java/com/google/common/html/types/SafeUrls.java
private static boolean isSafeUrl(String url, Set<CustomSafeUrlScheme> extraAllowedSchemes) {
    String lowerCased = url.toLowerCase();

    // If some Unicode character lower cases to something that ends up matching these ASCII ones,
    // it's harmless.
    for (String scheme : DEFAULT_SAFE_SCHEMES) {
      if (lowerCased.startsWith(scheme + ":")) {
        return true;
      }
    }

    for (CustomSafeUrlScheme scheme : extraAllowedSchemes) {
      /**
       * For "-" in a custom URL scheme, it's not possible to write a proto enum with "-" in the
       * field name. In proto, it has to be "_". But we can safely convert all "_" in the proto name
       * to "-", since according to the URL Living Standard, a URL-scheme string must be one ASCII
       * alpha, followed by zero or more of ASCII alphanumeric, "+", "-", and ".".
       *
       * @see https://url.spec.whatwg.org/#url-syntax
       */
      if (lowerCased.startsWith(scheme.name().toLowerCase().replace('_', '-') + ":")) {
        return true;
      }
    }

    for (int i = 0; i < url.length(); i++) {
      switch (url.charAt(i)) {
        case '/':
        case '?':
        case '#':
          // After this the string can end or contain anything else, it won't be interpreted
          // as the scheme.
          return true;
        case ':':
          // This character is not allowed before seeing one of the above characters.
          return false;
        default:
          // Other characters ok.
          continue;
      }
    }
    return true;
  }
private static boolean isSafeUrl(String url, Set<CustomSafeUrlScheme> extraAllowedSchemes) {
    String lowerCased = url.toLowerCase();

    // If some Unicode character lower cases to something that ends up matching these ASCII ones,
    // it's harmless.
    for (String scheme : DEFAULT_SAFE_SCHEMES) {
      if (lowerCased.startsWith(scheme + ":")) {
        return true;
      }
    }

    for (CustomSafeUrlScheme scheme : extraAllowedSchemes) {
      /**
       * For "-" in a custom URL scheme, it's not possible to write a proto enum with "-" in the
       * field name. In proto, it has to be "_". But we can safely convert all "_" in the proto name
       * to "-", since according to the URL Living Standard, a URL-scheme string must be one ASCII
       * alpha, followed by zero or more of ASCII alphanumeric, "+", "-", and ".".
       *
       * @see https://url.spec.whatwg.org/#url-syntax
       */
      if (lowerCased.startsWith(scheme.name().toLowerCase().replace('_', '-') + ":")) {
        return true;
      }
    }

    for (int i = 0; i < url.length(); i++) {
      switch (url.charAt(i)) {
        case '/':
        case '?':
        case '#':
          // After this the string can end or contain anything else, it won't be interpreted
          // as the scheme.
          return true;
        case ':':
          // This character is not allowed before seeing one of the above characters.
          return false;
        default:
          // Other characters ok.
          continue;
      }
    }
    return true;
  }
private static boolean isSafeUrl ( String url , Set < CustomSafeUrlScheme > extraAllowedSchemes ) { String lowerCased = url . toLowerCase ( ) ; // If some Unicode character lower cases to something that ends up matching these ASCII ones, // it's harmless. for ( String scheme : DEFAULT_SAFE_SCHEMES ) { if ( lowerCased . startsWith ( scheme + ":" ) ) { return true ; } } for ( CustomSafeUrlScheme scheme : extraAllowedSchemes ) { /**
       * For "-" in a custom URL scheme, it's not possible to write a proto enum with "-" in the
       * field name. In proto, it has to be "_". But we can safely convert all "_" in the proto name
       * to "-", since according to the URL Living Standard, a URL-scheme string must be one ASCII
       * alpha, followed by zero or more of ASCII alphanumeric, "+", "-", and ".".
       *
       * @see https://url.spec.whatwg.org/#url-syntax
       */ if ( lowerCased . startsWith ( scheme . name ( ) . toLowerCase ( ) . replace ( ' ' , ' ' ) + ":" ) ) { return true ; } } for ( int i = 0 ; i < url . length ( ) ; i ++ ) { switch ( url . charAt ( i ) ) { case ' ' : case ' ' : case ' ' : // After this the string can end or contain anything else, it won't be interpreted // as the scheme. return true ; case ' ' : // This character is not allowed before seeing one of the above characters. return false ; default : // Other characters ok. continue ; } } return true ; }
Matches a subset of URLs that will not cause script execution if used in URL context within a
HTML document. Specifically, this method returns true if the {@code url}:
<ul>
<li>Starts with a default safe protocol (http, https, ftp, mailto) or one of the schemes
specified in {@code extraAllowedSchemes}.
<li>Contains no protocol.  A protocol must be followed by a colon and colons are allowed
only after one of the characters [/?#].
A colon after a hash (#) must be in the fragment.
Otherwise, a colon after a (?) must be in a query.
Otherwise, a colon after a single solidus (/) must be in a path.
Otherwise, a colon after a double solidus (*) must be in the authority (before port).
</ul>

<p>We don't use a regex so that we don't need to depend on GWT, which does not support Java's
Pattern and requires using its RegExp class.
Matches a subset of URLs that will not cause script execution if used in URL context within a HTML document . Specifically this method returns true if the { @code url } : <ul > <li > Starts with a default safe protocol ( http https ftp mailto ) or one of the schemes specified in { @code extraAllowedSchemes } . <li > Contains no protocol . A protocol must be followed by a colon and colons are allowed only after one of the characters [ / ?# ] . A colon after a hash ( # ) must be in the fragment . Otherwise a colon after a ( ? ) must be in a query . Otherwise a colon after a single solidus ( / ) must be in a path . Otherwise a colon after a double solidus ( * ) must be in the authority ( before port ) . < / ul >