18403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// Copyright (c) 2011, Mike Samuel
28403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// All rights reserved.
38403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel//
48403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// Redistribution and use in source and binary forms, with or without
58403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// modification, are permitted provided that the following conditions
68403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// are met:
78403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel//
88403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// Redistributions of source code must retain the above copyright
98403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// notice, this list of conditions and the following disclaimer.
108403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// Redistributions in binary form must reproduce the above copyright
118403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// notice, this list of conditions and the following disclaimer in the
128403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// documentation and/or other materials provided with the distribution.
138403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// Neither the name of the OWASP nor the names of its contributors may
148403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// be used to endorse or promote products derived from this software
158403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// without specific prior written permission.
168403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
178403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
188403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
198403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
208403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
218403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
228403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
238403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
248403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
258403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
268403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
278403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// POSSIBILITY OF SUCH DAMAGE.
288403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel
294e867904c8295537803c1c8a076e130df5674b58mikesamuelpackage org.owasp.html;
304e867904c8295537803c1c8a076e130df5674b58mikesamuel
314e867904c8295537803c1c8a076e130df5674b58mikesamuel/**
324e867904c8295537803c1c8a076e130df5674b58mikesamuel * A URL checker optimized to avoid object allocation for the common case:
334e867904c8295537803c1c8a076e130df5674b58mikesamuel * {@code http}, {@code https}, {@code mailto}.
344e867904c8295537803c1c8a076e130df5674b58mikesamuel */
354e867904c8295537803c1c8a076e130df5674b58mikesamuel@TCB
364e867904c8295537803c1c8a076e130df5674b58mikesamuelfinal class StandardUrlAttributePolicy implements AttributePolicy {
374e867904c8295537803c1c8a076e130df5674b58mikesamuel
384e867904c8295537803c1c8a076e130df5674b58mikesamuel  static final StandardUrlAttributePolicy INSTANCE
394e867904c8295537803c1c8a076e130df5674b58mikesamuel      = new StandardUrlAttributePolicy();
404e867904c8295537803c1c8a076e130df5674b58mikesamuel
414e867904c8295537803c1c8a076e130df5674b58mikesamuel  private StandardUrlAttributePolicy() { /* singleton */ }
424e867904c8295537803c1c8a076e130df5674b58mikesamuel
434e867904c8295537803c1c8a076e130df5674b58mikesamuel  public String apply(String elementName, String attributeName, String s) {
444e867904c8295537803c1c8a076e130df5674b58mikesamuel    protocol_loop:
454e867904c8295537803c1c8a076e130df5674b58mikesamuel    for (int i = 0, n = s.length(); i < n; ++i) {
464e867904c8295537803c1c8a076e130df5674b58mikesamuel      switch (s.charAt(i)) {
474e867904c8295537803c1c8a076e130df5674b58mikesamuel        case '/': case '#': case '?':  // No protocol.
484e867904c8295537803c1c8a076e130df5674b58mikesamuel          break protocol_loop;
494e867904c8295537803c1c8a076e130df5674b58mikesamuel        case ':':
504e867904c8295537803c1c8a076e130df5674b58mikesamuel          switch (i) {
514e867904c8295537803c1c8a076e130df5674b58mikesamuel            case 4:
524e867904c8295537803c1c8a076e130df5674b58mikesamuel              if (!Strings.regionMatchesIgnoreCase("http", 0, s, 0, 4)) {
534e867904c8295537803c1c8a076e130df5674b58mikesamuel                return null;
544e867904c8295537803c1c8a076e130df5674b58mikesamuel              }
554e867904c8295537803c1c8a076e130df5674b58mikesamuel              break;
564e867904c8295537803c1c8a076e130df5674b58mikesamuel            case 5:
574e867904c8295537803c1c8a076e130df5674b58mikesamuel              if (!Strings.regionMatchesIgnoreCase("https", 0, s, 0, 5)) {
584e867904c8295537803c1c8a076e130df5674b58mikesamuel                return null;
594e867904c8295537803c1c8a076e130df5674b58mikesamuel              }
604e867904c8295537803c1c8a076e130df5674b58mikesamuel              break;
614e867904c8295537803c1c8a076e130df5674b58mikesamuel            case 6:
624e867904c8295537803c1c8a076e130df5674b58mikesamuel              if (!Strings.regionMatchesIgnoreCase("mailto", 0, s, 0, 6)) {
634e867904c8295537803c1c8a076e130df5674b58mikesamuel                return null;
644e867904c8295537803c1c8a076e130df5674b58mikesamuel              }
654e867904c8295537803c1c8a076e130df5674b58mikesamuel              break;
664e867904c8295537803c1c8a076e130df5674b58mikesamuel            default: return null;
674e867904c8295537803c1c8a076e130df5674b58mikesamuel          }
684e867904c8295537803c1c8a076e130df5674b58mikesamuel          break protocol_loop;
694e867904c8295537803c1c8a076e130df5674b58mikesamuel      }
704e867904c8295537803c1c8a076e130df5674b58mikesamuel    }
714e867904c8295537803c1c8a076e130df5674b58mikesamuel    return FilterUrlByProtocolAttributePolicy.normalizeUri(s);
724e867904c8295537803c1c8a076e130df5674b58mikesamuel  }
734e867904c8295537803c1c8a076e130df5674b58mikesamuel
744e867904c8295537803c1c8a076e130df5674b58mikesamuel}