This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.xss-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-xss.git

commit bc82200b533f02b27a2087cec17c193e80f32768
Author: Felix Meschberger <[email protected]>
AuthorDate: Thu Dec 11 09:15:04 2014 +0000

    SLING-4236 Clarify XSSAPI with respect to null and empty input strings
    
    * Include patch by Radu Cotescu (thanks a lot)
    * Extend patch to getValid* and filterHtml methods
    * Leverage TestCase.assertEquals for result validation
    * Add more tests for empty and null input
    * Add LongValidationRule
    
    git-svn-id: 
https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/xss@1644580 
13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            |   6 +
 src/main/java/org/apache/sling/xss/XSSAPI.java     |  65 ++++++----
 .../apache/sling/xss/impl/LongValidationRule.java  | 114 ++++++++++++++++++
 .../java/org/apache/sling/xss/impl/XSSAPIImpl.java | 127 ++++++++++---------
 .../org/apache/sling/xss/impl/XSSAPIImplTest.java  | 134 +++++++++++++++------
 5 files changed, 330 insertions(+), 116 deletions(-)

diff --git a/pom.xml b/pom.xml
index b1e95fb..af111f4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -265,6 +265,12 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
+            <groupId>com.google.code.findbugs</groupId>
+            <artifactId>jsr305</artifactId>
+            <version>2.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <scope>test</scope>
diff --git a/src/main/java/org/apache/sling/xss/XSSAPI.java 
b/src/main/java/org/apache/sling/xss/XSSAPI.java
index 0e026b3..f9fc0a8 100644
--- a/src/main/java/org/apache/sling/xss/XSSAPI.java
+++ b/src/main/java/org/apache/sling/xss/XSSAPI.java
@@ -17,6 +17,9 @@
 package org.apache.sling.xss;
 
 
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.resource.ResourceResolver;
 
@@ -42,33 +45,36 @@ public interface XSSAPI {
 
     /**
      * Validate a string which should contain an integer, returning a default 
value if the source is
-     * empty, can't be parsed, or contains XSS risks.
+     * {@code null}, empty, can't be parsed, or contains XSS risks.
      *
      * @param integer      the source integer
-     * @param defaultValue a default value if the source can't be used
+     * @param defaultValue a default value if the source can't be used, is 
{@code null} or an empty string
      * @return a sanitized integer
      */
-    public Integer getValidInteger(String integer, int defaultValue);
+    @Nullable
+    public Integer getValidInteger(@Nullable String integer, @Nullable int 
defaultValue);
 
     /**
      * Validate a string which should contain a long, returning a default 
value if the source is
-     * empty, can't be parsed, or contains XSS risks.
+     * {@code null}, empty, can't be parsed, or contains XSS risks.
      *
      * @param source       the source long
-     * @param defaultValue a default value if the source can't be used
+     * @param defaultValue a default value if the source can't be used, is 
{@code null} or an empty string
      * @return a sanitized integer
      */
-    public Long getValidLong(String source, long defaultValue);
+    @Nullable
+    public Long getValidLong(@Nullable String source, @Nullable long 
defaultValue);
 
     /**
      * Validate a string which should contain a dimension, returning a default 
value if the source is
      * empty, can't be parsed, or contains XSS risks.  Allows integer 
dimensions and the keyword "auto".
      *
      * @param dimension    the source dimension
-     * @param defaultValue a default value if the source can't be used
+     * @param defaultValue a default value if the source can't be used, is 
{@code null} or an empty string
      * @return a sanitized dimension
      */
-    public String getValidDimension(String dimension, String defaultValue);
+    @Nullable
+    public String getValidDimension(@Nullable String dimension, @Nullable 
String defaultValue);
 
     /**
      * Sanitizes a URL for writing as an HTML href or src attribute value.
@@ -76,27 +82,30 @@ public interface XSSAPI {
      * @param url the source URL
      * @return a sanitized URL (possibly empty)
      */
-    public String getValidHref(String url);
+    @Nonnull
+    public String getValidHref(@Nullable String url);
 
     /**
      * Validate a Javascript token.  The value must be either a single 
identifier, a literal number,
      * or a literal string.
      *
      * @param token        the source token
-     * @param defaultValue a default value to use if the source doesn't meet 
validity constraints.
+     * @param defaultValue a default value to use if the source is {@code 
null}, an empty string, or doesn't meet validity constraints.
      * @return a string containing a single identifier, a literal number, or a 
literal string token
      */
-    public String getValidJSToken(String token, String defaultValue);
+    @Nullable
+    public String getValidJSToken(@Nullable String token, @Nullable String 
defaultValue);
 
     /**
      * Validate a style/CSS token. Valid CSS tokens are specified at 
http://www.w3.org/TR/css3-syntax/
      *
      * @param token        the source token
-     * @param defaultValue a default value to use if the source doesn't meet 
validity constraints.
+     * @param defaultValue a default value to use if the source is {@code 
null}, an empty string, or doesn't meet validity constraints.
      *
      * @return a string containing sanitized style token
      */
-    public String getValidStyleToken(String token, String defaultValue);
+    @Nullable
+    public String getValidStyleToken(@Nullable String token, @Nullable String 
defaultValue);
 
     /**
      * Validate a CSS color value. Color values as specified at 
http://www.w3.org/TR/css3-color/#colorunits
@@ -104,10 +113,11 @@ public interface XSSAPI {
      * vulnerable constructs include url(...), expression(...), and anything 
with a semicolon.
      *
      * @param color        the color value to be used.
-     * @param defaultColor a default value to use if the input color value 
doesn't meet validity constraints.
+     * @param defaultColor a default value to use if the input color value is 
{@code null}, an empty string, doesn't meet validity constraints.
      * @return a string a css color value.
      */
-    public String getValidCSSColor(String color, String defaultColor);
+    @Nullable
+    public String getValidCSSColor(@Nullable String color, @Nullable String 
defaultColor);
 
     // 
=============================================================================================
     // ENCODERS
@@ -120,7 +130,8 @@ public interface XSSAPI {
      * @param source the input to encode
      * @return an encoded version of the source
      */
-    public String encodeForHTML(String source);
+    @Nullable
+    public String encodeForHTML(@Nullable String source);
 
     /**
      * Encodes a source string for writing to an HTML attribute value.
@@ -129,7 +140,8 @@ public interface XSSAPI {
      * @param source the input to encode
      * @return an encoded version of the source
      */
-    public String encodeForHTMLAttr(String source);
+    @Nullable
+    public String encodeForHTMLAttr(@Nullable String source);
 
     /**
      * Encodes a source string for XML element content.
@@ -138,7 +150,8 @@ public interface XSSAPI {
      * @param source the input to encode
      * @return an encoded version of the source
      */
-    public String encodeForXML(String source);
+    @Nullable
+    public String encodeForXML(@Nullable String source);
 
     /**
      * Encodes a source string for writing to an XML attribute value.
@@ -146,7 +159,8 @@ public interface XSSAPI {
      * @param source the input to encode
      * @return an encoded version of the source
      */
-    public String encodeForXMLAttr(String source);
+    @Nullable
+    public String encodeForXMLAttr(@Nullable String source);
 
     /**
      * Encodes a source string for writing to JavaScript string content.
@@ -156,17 +170,19 @@ public interface XSSAPI {
      * @param source the input to encode
      * @return an encoded version of the source
      */
-    public String encodeForJSString(String source);
+    @Nullable
+    public String encodeForJSString(@Nullable String source);
 
     /**
-     * Encodes a souce string for writing to CSS string content.
+     * Encodes a source string for writing to CSS string content.
      * DO NOT USE FOR WRITING OUT ARBITRARY CSS TOKENS; YOU MUST USE A 
VALIDATOR FOR THAT!
      * (Encoding only ensures the source string cannot break out of its 
context.)
      *
      * @param source the input to encode
      * @return an encoded version of the source
      */
-    public String encodeForCSSString(String source);
+    @Nullable
+    public String encodeForCSSString(@Nullable String source);
 
 
     // 
=============================================================================================
@@ -178,9 +194,10 @@ public interface XSSAPI {
      * effect for HTML output (see the XSSFilter service for details).
      *
      * @param source a string containing the source HTML
-     * @return a string containing the sanitized HTML
+     * @return a string containing the sanitized HTML which may be an empty 
string if {@code source} is {@code null} or empty
      */
-    public String filterHTML(String source);
+    @Nonnull
+    public String filterHTML(@Nullable String source);
 
 
     // 
=============================================================================================
diff --git a/src/main/java/org/apache/sling/xss/impl/LongValidationRule.java 
b/src/main/java/org/apache/sling/xss/impl/LongValidationRule.java
new file mode 100644
index 0000000..7d258d9
--- /dev/null
+++ b/src/main/java/org/apache/sling/xss/impl/LongValidationRule.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * OWASP Enterprise Security API (ESAPI)
+ *
+ * This file is part of the Open Web Application Security Project (OWASP)
+ * Enterprise Security API (ESAPI) project. For details, please see
+ * <a 
href="http://www.owasp.org/index.php/ESAPI";>http://www.owasp.org/index.php/ESAPI</a>.
+ *
+ * Copyright (c) 2007 - The OWASP Foundation
+ *
+ * The ESAPI is published by OWASP under the BSD license. You should read and 
accept the
+ * LICENSE before you use, modify, and/or redistribute this software.
+ *
+ * @author Jeff Williams <a href="http://www.aspectsecurity.com";>Aspect 
Security</a>
+ * @created 2007
+ */
+package org.apache.sling.xss.impl;
+
+import org.apache.sling.xss.XSSAPI;
+import org.owasp.esapi.Encoder;
+import org.owasp.esapi.StringUtilities;
+import org.owasp.esapi.errors.ValidationException;
+import org.owasp.esapi.reference.validation.BaseValidationRule;
+
+
+/**
+ * A validator performs syntax and possibly semantic validation of a single
+ * piece of data from an untrusted source.
+ * <p>
+ * This class is derived from the OWASP ESAPI {@code LongValidationRule}
+ * class to support validation of {@code long} values.
+ *
+ * @see XSSAPI#getValidLong(String, long)
+ * @see org.owasp.esapi.Validator
+ * @see org.owasp.esapi.reference.validation.IntegerValidationRule
+ */
+class LongValidationRule extends BaseValidationRule {
+
+    private final long minValue;
+    private final long maxValue;
+
+    LongValidationRule( String typeName, Encoder encoder, long minValue, long 
maxValue ) {
+        super( typeName, encoder );
+        this.minValue = minValue;
+        this.maxValue = maxValue;
+    }
+
+    public Long getValid( String context, String input ) throws 
ValidationException {
+        return safelyParse(context, input);
+    }
+
+    private Long safelyParse(String context, String input) throws 
ValidationException {
+        // do not allow empty Strings such as "   " - so trim to ensure
+        // isEmpty catches "    "
+        if (input != null) input = input.trim();
+
+        if ( StringUtilities.isEmpty(input) ) {
+            if (allowNull) {
+                return null;
+            }
+            throw new ValidationException( context + ": Input number 
required", "Input number required: context=" + context + ", input=" + input, 
context );
+        }
+
+        // canonicalize
+        String canonical = encoder.canonicalize( input );
+
+        if (minValue > maxValue) {
+            throw new ValidationException( context + ": Invalid number input: 
context", "Validation parameter error for number: maxValue ( " + maxValue + ") 
must be greater than minValue ( " + minValue + ") for " + context, context );
+        }
+
+        // validate min and max
+        try {
+            long i = Long.valueOf(canonical);
+            if (i < minValue) {
+                throw new ValidationException( "Invalid number input must be 
between " + minValue + " and " + maxValue + ": context=" + context, "Invalid 
number input must be between " + minValue + " and " + maxValue + ": context=" + 
context + ", input=" + input, context );
+            }
+            if (i > maxValue) {
+                throw new ValidationException( "Invalid number input must be 
between " + minValue + " and " + maxValue + ": context=" + context, "Invalid 
number input must be between " + minValue + " and " + maxValue + ": context=" + 
context + ", input=" + input, context );
+            }
+            return i;
+        } catch (NumberFormatException e) {
+            throw new ValidationException( context + ": Invalid number input", 
"Invalid number input format: context=" + context + ", input=" + input, e, 
context);
+        }
+    }
+
+    @Override
+    public Long sanitize( String context, String input ) {
+        Long toReturn = Long.valueOf( 0 );
+        try {
+            toReturn = safelyParse(context, input);
+        } catch (ValidationException e ) {
+            // do nothing
+        }
+        return toReturn;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/xss/impl/XSSAPIImpl.java 
b/src/main/java/org/apache/sling/xss/impl/XSSAPIImpl.java
index e01aff1..bddab78 100644
--- a/src/main/java/org/apache/sling/xss/impl/XSSAPIImpl.java
+++ b/src/main/java/org/apache/sling/xss/impl/XSSAPIImpl.java
@@ -44,50 +44,60 @@ public class XSSAPIImpl implements XSSAPI {
 
     private Validator validator = ESAPI.validator();
 
+    private static final Pattern PATTERN_AUTO_DIMENSION = 
Pattern.compile("['\"]?auto['\"]?");
+
     /**
      * @see org.apache.sling.xss.XSSAPI#getValidInteger(String, int)
      */
     public Integer getValidInteger(String integer, int defaultValue) {
-        try {
-            if (integer == null || integer.length() == 0) {
-                return defaultValue;
-            } else {
+        if (integer != null && integer.length() > 0) {
+            try {
                 return validator.getValidInteger("XSS", integer, -2000000000, 
2000000000, false);
+            } catch (Exception e) {
+                // ignore
             }
-        } catch (Exception e) {
-            return defaultValue;
         }
+
+        // fall through to default if empty, null, or validation failure
+        return defaultValue;
     }
 
     /**
      * @see org.apache.sling.xss.XSSAPI#getValidLong(String, long)
      */
     public Long getValidLong(String source, long defaultValue) {
-        try {
-            if (source == null || source.length() == 0) {
-                return defaultValue;
-            } else {
-                return validator.getValidNumber("XSS", source, 
-9000000000000000000L, 9000000000000000000L, false).longValue();
+        if (source != null && source.length() > 0) {
+            try {
+                LongValidationRule ivr = new LongValidationRule( "number", 
ESAPI.encoder(), -9000000000000000000L, 9000000000000000000L );
+                ivr.setAllowNull(false);
+                return ivr.getValid("XSS", source);
+            } catch (Exception e) {
+                // ignore
             }
-        } catch (Exception e) {
-            return defaultValue;
         }
+
+        // fall through to default if empty, null, or validation failure
+        return defaultValue;
     }
 
     /**
      * @see org.apache.sling.xss.XSSAPI#getValidDimension(String, String)
      */
     public String getValidDimension(String dimension, String defaultValue) {
-        try {
-            if (dimension == null || dimension.length() == 0) {
-                return defaultValue;
-            } else if (dimension.matches("['\"]?auto['\"]?")) {
+        if (dimension != null && dimension.length() > 0) {
+            if (PATTERN_AUTO_DIMENSION.matcher(dimension).matches()) {
                 return "\"auto\"";
             }
-            return validator.getValidInteger("XSS", dimension, -10000, 10000, 
false).toString();
-        } catch (Exception e) {
-            return defaultValue;
+
+            try {
+                return validator.getValidInteger("XSS", dimension, -10000, 
10000, false).toString();
+            } catch (Exception e) {
+                // ignore
+            }
         }
+
+        // fall through to default if empty, null, or validation failure
+        return defaultValue;
     }
 
     private static final String LINK_PREFIX = "<a href=\"";
@@ -147,7 +157,7 @@ public class XSSAPIImpl implements XSSAPI {
      * @see org.apache.sling.xss.XSSAPI#getValidHref(String)
      */
     public String getValidHref(final String url) {
-        try {
+        if (url != null && url.length() > 0) {
             // Percent-encode characters that are not allowed in unquoted
             // HTML attributes: ", ', >, <, ` and space. We don't encode =
             // since this would break links with query parameters.
@@ -163,31 +173,32 @@ public class XSSAPIImpl implements XSSAPI {
             final String safeHtml = 
xssFilter.filter(ProtectionContext.HTML_HTML_CONTENT, testHtml);
             // if the xssFilter didn't like the input string we just return ""
             // otherwise we return the mangled url without encoding
-            if (!safeHtml.equals(testHtml)) {
-                return "";
-            } else {
+            if (safeHtml.equals(testHtml)) {
                 return mangleNamespaces(encodedUrl);
             }
-        } catch (final NullPointerException e) {
-            // ProtectionContext was null - simply return an empty string
-            return "";
         }
+
+        // fall through to empty string
+        return "";
     }
 
     /**
      * @see org.apache.sling.xss.XSSAPI#getValidJSToken(String, String)
      */
     public String getValidJSToken(String token, String defaultValue) {
-        token = token.trim();
-        String q = token.substring(0, 1);
-        if (q.matches("['\"]") && token.endsWith(q)) {
-            String literal = token.substring(1, token.length() - 1);
-            return q + encodeForJSString(literal) + q;
-        } else if (token.matches("[0-9a-zA-Z_$][0-9a-zA-Z_$.]*")) {
-            return token;
-        } else {
-            return defaultValue;
+        if (token != null && token.length() > 0) {
+            token = token.trim();
+            String q = token.substring(0, 1);
+            if (q.matches("['\"]") && token.endsWith(q)) {
+                String literal = token.substring(1, token.length() - 1);
+                return q + encodeForJSString(literal) + q;
+            } else if (token.matches("[0-9a-zA-Z_$][0-9a-zA-Z_$.]*")) {
+                return token;
+            }
         }
+
+        // fall through to default value
+        return defaultValue;
     }
 
     private static final String NON_ASCII = "\\x00\\x08\\x0B\\x0C\\x0E-\\x1F";
@@ -224,29 +235,33 @@ public class XSSAPIImpl implements XSSAPI {
      * @see org.apache.sling.xss.XSSAPI#getValidStyleToken(String, String)
      */
     public String getValidStyleToken(String token, String defaultValue) {
-        if (token.matches(CSS_TOKEN)) {
+        if (token != null && token.length() > 0 && token.matches(CSS_TOKEN)) {
             return token;
         }
+
         return defaultValue;
-    }
+   }
 
     /**
      * @see org.apache.sling.xss.XSSAPI#getValidCSSColor(String, String)
      */
     public String getValidCSSColor(String color, String defaultColor) {
-        color = color.trim();
-        /*
-         * Avoid security implications by including only the characters 
required to specify colors in hex
-         * or functional notation. Critical characters disallowed: x (as in 
expression(...)),
-         * u (as in url(...)) and semi colon (as in escaping the context of 
the color value). 
-         */
-        if (color.matches("(?i)[#a-fghlrs(+0-9-.%,) \\t\\n\\x0B\\f\\r]+")) {
-            return color;
-        }
-        // named color values
-        if (color.matches("(?i)[a-zA-Z \\t\\n\\x0B\\f\\r]+")) {
-            return color;
+        if (color != null && color.length() > 0) {
+            color = color.trim();
+            /*
+             * Avoid security implications by including only the characters 
required to specify colors in hex
+             * or functional notation. Critical characters disallowed: x (as 
in expression(...)),
+             * u (as in url(...)) and semi colon (as in escaping the context 
of the color value).
+             */
+            if (color.matches("(?i)[#a-fghlrs(+0-9-.%,) \\t\\n\\x0B\\f\\r]+")) 
{
+                return color;
+            }
+            // named color values
+            if (color.matches("(?i)[a-zA-Z \\t\\n\\x0B\\f\\r]+")) {
+                return color;
+            }
         }
+
         return defaultColor;
     }
 
@@ -258,42 +273,42 @@ public class XSSAPIImpl implements XSSAPI {
      * @see org.apache.sling.xss.XSSAPI#encodeForHTML(String)
      */
     public String encodeForHTML(String source) {
-        return Encode.forHtml(source);
+        return source == null ? null : Encode.forHtml(source);
     }
 
     /**
      * @see org.apache.sling.xss.XSSAPI#encodeForHTMLAttr(String)
      */
     public String encodeForHTMLAttr(String source) {
-        return Encode.forHtmlAttribute(source);
+        return source == null ? null : Encode.forHtmlAttribute(source);
     }
 
     /**
      * @see org.apache.sling.xss.XSSAPI#encodeForXML(String)
      */
     public String encodeForXML(String source) {
-        return Encode.forXml(source);
+        return source == null ? null : Encode.forXml(source);
     }
 
     /**
      * @see org.apache.sling.xss.XSSAPI#encodeForXMLAttr(String)
      */
     public String encodeForXMLAttr(String source) {
-        return Encode.forXmlAttribute(source);
+        return source == null ? null : Encode.forXmlAttribute(source);
     }
 
     /**
      * @see org.apache.sling.xss.XSSAPI#encodeForJSString(String)
      */
     public String encodeForJSString(String source) {
-        return Encode.forJavaScript(source);
+        return source == null ? null : Encode.forJavaScript(source);
     }
 
     /**
      * @see org.apache.sling.xss.XSSAPI#encodeForCSSString(String)
      */
     public String encodeForCSSString(String source) {
-        return Encode.forCssString(source);
+        return source == null ? null : Encode.forCssString(source);
     }
 
     // 
=============================================================================================
diff --git a/src/test/java/org/apache/sling/xss/impl/XSSAPIImplTest.java 
b/src/test/java/org/apache/sling/xss/impl/XSSAPIImplTest.java
index 1367810..a826b06 100644
--- a/src/test/java/org/apache/sling/xss/impl/XSSAPIImplTest.java
+++ b/src/test/java/org/apache/sling/xss/impl/XSSAPIImplTest.java
@@ -26,6 +26,8 @@ import java.io.InputStream;
 import java.lang.reflect.Field;
 import java.util.Map;
 
+import junit.framework.TestCase;
+
 import org.apache.sling.xss.XSSAPI;
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.resource.ResourceResolver;
@@ -87,6 +89,7 @@ public class XSSAPIImplTest {
         String[][] testData = {
                 //         Source                            Expected Result
                 //
+                {null, null},
                 {"simple", "simple"},
 
                 {"<script>", "&lt;script&gt;"},
@@ -100,10 +103,29 @@ public class XSSAPIImplTest {
             String source = aTestData[0];
             String expected = aTestData[1];
 
-            String result = xssAPI.encodeForHTML(source);
-            if (!result.equals(expected)) {
-                fail("HTML Encoding '" + source + "', expecting '" + expected 
+ "', but got '" + result + "'");
-            }
+            TestCase.assertEquals("HTML Encoding '" + source + "'", expected, 
xssAPI.encodeForHTML(source));
+        }
+    }
+
+    @Test
+    public void TestEncodeForHTMLAttr() {
+        String[][] testData = {
+                //         Source                            Expected Result
+                //
+                {null, null},
+                {"simple", "simple"},
+
+                {"<script>", "&lt;script>"},
+                {"\" <script>alert('pwned');</script>", "&#34; 
&lt;script>alert(&#39;pwned&#39;);&lt;/script>"},
+                {"günter", "günter"},
+                
{"\u30e9\u30c9\u30af\u30ea\u30d5\u3001\u30de\u30e9\u30bd\u30f3\u4e94\u8f2a\u4ee3\u8868\u306b1\u4e07m\u51fa\u5834\u306b\u3082\u542b\u307f",
 
"\u30e9\u30c9\u30af\u30ea\u30d5\u3001\u30de\u30e9\u30bd\u30f3\u4e94\u8f2a\u4ee3\u8868\u306b1\u4e07m\u51fa\u5834\u306b\u3082\u542b\u307f"}
+        };
+
+        for (String[] aTestData : testData) {
+            String source = aTestData[0];
+            String expected = aTestData[1];
+
+            TestCase.assertEquals("HTML Encoding '" + source + "'", expected, 
xssAPI.encodeForHTMLAttr(source));
         }
     }
 
@@ -112,6 +134,7 @@ public class XSSAPIImplTest {
         String[][] testData = {
                 //         Source                            Expected Result
                 //
+                {null, null},
                 {"simple", "simple"},
 
                 {"<script>", "&lt;script&gt;"},
@@ -124,10 +147,30 @@ public class XSSAPIImplTest {
             String source = aTestData[0];
             String expected = aTestData[1];
 
-            String result = xssAPI.encodeForXML(source);
-            if (!result.equals(expected)) {
-                fail("XML Encoding '" + source + "', expecting '" + expected + 
"', but got '" + result + "'");
-            }
+            TestCase.assertEquals("XML Encoding '" + source + "'", expected, 
xssAPI.encodeForXML(source));
+        }
+    }
+
+    @Test
+    public void TestEncodeForXMLAttr() {
+        String[][] testData = {
+                //         Source                            Expected Result
+                //
+                {null, null},
+                {"simple", "simple"},
+
+                {"<script>", "&lt;script>"},
+                {"<b>", "&lt;b>"},
+
+                {"günter", "günter"},
+                {"\"xss:expression(alert('XSS'))", 
"&#34;xss:expression(alert(&#39;XSS&#39;))"}
+        };
+
+        for (String[] aTestData : testData) {
+            String source = aTestData[0];
+            String expected = aTestData[1];
+
+            TestCase.assertEquals("XML Encoding '" + source + "'", expected, 
xssAPI.encodeForXMLAttr(source));
         }
     }
 
@@ -135,6 +178,8 @@ public class XSSAPIImplTest {
     public void TestFilterHTML() {
         String[][] testData = {
                 //         Source                            Expected Result
+                {null, ""},
+                {"", ""},
                 {"simple", "simple"},
 
                 {"<script>ugly</script>", ""},
@@ -160,10 +205,7 @@ public class XSSAPIImplTest {
             String source = aTestData[0];
             String expected = aTestData[1];
 
-            String result = xssAPI.filterHTML(source);
-            if (!result.equals(expected)) {
-                fail("Filtering '" + source + "', expecting '" + expected + 
"', but got '" + result + "'");
-            }
+            TestCase.assertEquals("Filtering '" + source + "'", expected, 
xssAPI.filterHTML(source));
         }
     }
 
@@ -172,6 +214,8 @@ public class XSSAPIImplTest {
         String[][] testData = {
                 //         Href                                        
Expected Result
                 //
+                {null, ""},
+                {"", ""},
                 {"simple", "simple"},
 
                 {"../parent", "../parent"},
@@ -217,10 +261,7 @@ public class XSSAPIImplTest {
             String href = aTestData[0];
             String expected = aTestData[1];
 
-            String result = xssAPI.getValidHref(href);
-            if (!result.equals(expected)) {
-                fail("Requested '" + href + "', expecting '" + expected + "', 
but got '" + result + "'");
-            }
+            TestCase.assertEquals("Requested '" + href + "'", expected, 
xssAPI.getValidHref(href));
         }
     }
 
@@ -229,6 +270,7 @@ public class XSSAPIImplTest {
         String[][] testData = {
                 //         Source                                        
Expected Result
                 //
+                {null, "123"},
                 {"100", "100"},
                 {"0", "0"},
 
@@ -240,12 +282,32 @@ public class XSSAPIImplTest {
 
         for (String[] aTestData : testData) {
             String source = aTestData[0];
-            int expected = new Integer(aTestData[1]);
+            Integer expected = (aTestData[1] != null) ? new 
Integer(aTestData[1]) : null;
 
-            int result = xssAPI.getValidInteger(source, 123);
-            if (result != expected) {
-                fail("Validating integer '" + source + "', expecting '" + 
expected + "', but got '" + result + "'");
-            }
+            TestCase.assertEquals("Validating integer '" + source + "'", 
expected, xssAPI.getValidInteger(source, 123));
+        }
+    }
+
+    @Test
+    public void TestGetValidLong() {
+        String[][] testData = {
+                //         Source                                        
Expected Result
+                //
+                {null, "123"},
+                {"100", "100"},
+                {"0", "0"},
+
+                {"junk", "123"},
+                {"100.5", "123"},
+                {"", "123"},
+                {"null", "123"}
+        };
+
+        for (String[] aTestData : testData) {
+            String source = aTestData[0];
+            Long expected = (aTestData[1] != null) ? new Long(aTestData[1]) : 
null;
+
+            TestCase.assertEquals("Validating long '" + source + "'", 
expected, xssAPI.getValidLong(source, 123));
         }
     }
 
@@ -254,6 +316,8 @@ public class XSSAPIImplTest {
         String[][] testData = {
                 //         Source                                        
Expected Result
                 //
+                {null, "123"},
+                {"", "123"},
                 {"100", "100"},
                 {"0", "0"},
 
@@ -273,10 +337,7 @@ public class XSSAPIImplTest {
             String source = aTestData[0];
             String expected = aTestData[1];
 
-            String result = xssAPI.getValidDimension(source, "123");
-            if (!result.equals(expected)) {
-                fail("Validating dimension '" + source + "', expecting '" + 
expected + "', but got '" + result + "'");
-            }
+            TestCase.assertEquals("Validating dimension '" + source + "'", 
expected, xssAPI.getValidDimension(source, "123"));
         }
     }
 
@@ -285,6 +346,7 @@ public class XSSAPIImplTest {
         String[][] testData = {
                 //         Source                            Expected Result
                 //
+                {null, null},
                 {"simple", "simple"},
 
                 {"break\"out", "break\\x22out"},
@@ -297,10 +359,7 @@ public class XSSAPIImplTest {
             String source = aTestData[0];
             String expected = aTestData[1];
 
-            String result = xssAPI.encodeForJSString(source);
-            if (!result.equals(expected)) {
-                fail("Encoding '" + source + "', expecting '" + expected + "', 
but got '" + result + "'");
-            }
+            TestCase.assertEquals("Encoding '" + source + "'", expected, 
xssAPI.encodeForJSString(source));
         }
     }
 
@@ -309,6 +368,8 @@ public class XSSAPIImplTest {
         String[][] testData = {
                 //         Source                            Expected Result
                 //
+                {null, RUBBISH},
+                {"", RUBBISH},
                 {"simple", "simple"},
                 {"clickstreamcloud.thingy", "clickstreamcloud.thingy"},
 
@@ -330,10 +391,7 @@ public class XSSAPIImplTest {
             String source = aTestData[0];
             String expected = aTestData[1];
 
-            String result = xssAPI.getValidJSToken(source, RUBBISH);
-            if (!result.equals(expected)) {
-                fail("Validating Javascript token '" + source + "', expecting 
'" + expected + "', but got '" + result + "'");
-            }
+            TestCase.assertEquals("Validating Javascript token '" + source + 
"'", expected, xssAPI.getValidJSToken(source, RUBBISH));
         }
     }
 
@@ -341,6 +399,7 @@ public class XSSAPIImplTest {
     public void TestEncodeForCSSString() {
         String[][] testData = {
                 // Source   Expected result
+                {null, null},
                 {"test"   , "test"},
                 {"\\"     , "\\5c"},
                 {"'"      , "\\27"},
@@ -352,9 +411,7 @@ public class XSSAPIImplTest {
             String expected = aTestData[1];
 
             String result = xssAPI.encodeForCSSString(source);
-            if (!result.equals(expected)) {
-                fail("Encoding '" + source + "', expecting '" + expected + "', 
but got '" + result + "'");
-            }
+            TestCase.assertEquals("Encoding '" + source + "'", expected, 
result);
         }
     }
 
@@ -362,6 +419,8 @@ public class XSSAPIImplTest {
     public void TestGetValidStyleToken() {
         String[][] testData = {
                 // Source                           Expected result
+                {null                               , RUBBISH},
+                {""                                 , RUBBISH},
 
                 // CSS close
                 {"}"                                , RUBBISH},
@@ -429,6 +488,9 @@ public class XSSAPIImplTest {
         String[][] testData = {
                 //      Source                          Expected Result
                 //
+                {null, RUBBISH},
+                {"", RUBBISH},
+
                 {"rgb(0,+0,-0)", "rgb(0,+0,-0)"},
                 {"rgba ( 0\f%, 0%,\t0%,\n100%\r)", "rgba ( 0\f%, 
0%,\t0%,\n100%\r)",},
 

-- 
To stop receiving notification emails like this one, please contact
"[email protected]" <[email protected]>.

Reply via email to