You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2009/04/22 15:25:57 UTC

svn commit: r767511 - in /jackrabbit/branches/1.5: ./ jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/ jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/value/ jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/util/

Author: jukka
Date: Wed Apr 22 13:25:56 2009
New Revision: 767511

URL: http://svn.apache.org/viewvc?rev=767511&view=rev
Log:
1.5: Merged revisions 747096 and 748065 (JCR-1976 and JCR-1997)

Modified:
    jackrabbit/branches/1.5/   (props changed)
    jackrabbit/branches/1.5/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/Text.java
    jackrabbit/branches/1.5/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/value/ValueHelper.java
    jackrabbit/branches/1.5/jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/util/TextTest.java

Propchange: jackrabbit/branches/1.5/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Apr 22 13:25:56 2009
@@ -1,2 +1,2 @@
 /jackrabbit/branches/1.3:631261
-/jackrabbit/trunk:703899-704158,704165,704167,704324,704358,704361,704864,704933,704939,705010,705033,705243,705496,705522,705579,705925,705932,705934,705937-705938,705961,706242,706273,706285-706286,706562,706606,706649,706655,706660,706697,706918,707303-707304,707307,707310,707630,708206,708598,708609,708613,708619,708634,708840,708863,708909,708929,708943,709115,709142,709207,709211,710047,711238,711566-711567,711595,711841-711843,712984-712985,713037,713059,713065,713072,713076,713162,713214,713956,713958,713964,713971,713975,714034,718218,718249-718250,718371,718376,718566,718632,718981,719225,719282,719575-719577,719579,719585-719586,719588,719592,720455,720484,720492,720524,720533,720540,720673,720679,720687,720784,720940,720969,721186,721191,721194,721235,721387-721389,721470,721495,722068-722069,722463,722465,722467,722470,722825,723281,723346,723728,723784,724300,724387,725292,727376,727388,727390,727395,727397,727402,727492,727701,728022,731896,731934,731941,73234
 7,732678,732686,732689,732693,732703,732715-732716,732719,732728,732730,732734-732738,732740,732742-732743,732745,732867,732883,733057-733059,733061,733080,734092,734366,734375,734400,734709,735401,736021,736030,736274,736276,736650-736651,736653-736656,736658,736680,737695,738087,738119,738121,738419,738422,738474,738512,739210,739212,739226,740262,740734,740736-740738,740747,740749-740750,741052,741100,741121,741206,741208-741210,741213,741509,741524,741652,741803,742382,742538,743295,743713,743718,743726,743734,743738,744883-744884,744889,744895,744911,744935,744940,744954,744956,745041,745051,745053,745056,745060,745120,745500,745534,745824,745849,746301-746302,746486,746602-746603,746609,746666,746747-746748,747325,747347,747358-747360,747362,747365,747368,747372,747785,747839,748232-748233,748247,748486,749237,749448,749622,749953,749965,750011,750437,752036-752039,752044,752046-752051,752053-752054,752056,752058-752060,752063-752067,752115,752131,752414-752415,752478,
 752543-752545,752809,752831,752840-752841,753225-753228,753232,753244,755582,756378,756403,756405,756409,756429,756432,756442,756444-756445,757364,757698,757775-757776,757814,757854,757856,757862,758193,758263,758265,758349,758354,758629,758632,758634-758636,758639-758642,758646,758649,758653-758654,759880,759889,760386,760479,760945,761267,761279-761280,761282-761283,761292,761634,761645,761690-761691,761715,762671,762675,762700,762702,762731,762737,762755,762780-762781,762789,762793,762797,762802,762804,762808,762813-762814,762817-762818,762821-762823,763146,763160,763188,763205,763215,763242,763244,763248,763617,765322,765328,765337,765532,765551,765554,765556,765585
+/jackrabbit/trunk:703899-704158,704165,704167,704324,704358,704361,704864,704933,704939,705010,705033,705243,705496,705522,705579,705925,705932,705934,705937-705938,705961,706242,706273,706285-706286,706562,706606,706649,706655,706660,706697,706918,707303-707304,707307,707310,707630,708206,708598,708609,708613,708619,708634,708840,708863,708909,708929,708943,709115,709142,709207,709211,710047,711238,711566-711567,711595,711841-711843,712984-712985,713037,713059,713065,713072,713076,713162,713214,713956,713958,713964,713971,713975,714034,718218,718249-718250,718371,718376,718566,718632,718981,719225,719282,719575-719577,719579,719585-719586,719588,719592,720455,720484,720492,720524,720533,720540,720673,720679,720687,720784,720940,720969,721186,721191,721194,721235,721387-721389,721470,721495,722068-722069,722463,722465,722467,722470,722825,723281,723346,723728,723784,724300,724387,725292,727376,727388,727390,727395,727397,727402,727492,727701,728022,731896,731934,731941,73234
 7,732678,732686,732689,732693,732703,732715-732716,732719,732728,732730,732734-732738,732740,732742-732743,732745,732867,732883,733057-733059,733061,733080,734092,734366,734375,734400,734709,735401,736021,736030,736274,736276,736650-736651,736653-736656,736658,736680,737695,738087,738119,738121,738419,738422,738474,738512,739210,739212,739226,740262,740734,740736-740738,740747,740749-740750,741052,741100,741121,741206,741208-741210,741213,741509,741524,741652,741803,742382,742538,743295,743713,743718,743726,743734,743738,744883-744884,744889,744895,744911,744935,744940,744954,744956,745041,745051,745053,745056,745060,745120,745500,745534,745824,745849,746301-746302,746486,746602-746603,746609,746666,746747-746748,746932,746946,747096,747325,747347,747358-747360,747362,747365,747368,747372,747785,747839,748065,748232-748233,748247,748486,749237,749448,749622,749953,749965,750011,750437,752036-752039,752044,752046-752051,752053-752054,752056,752058-752060,752063-752067,752115,
 752131,752414-752415,752478,752543-752545,752809,752831,752840-752841,753225-753228,753232,753244,755582,756378,756403,756405,756409,756429,756432,756442,756444-756445,757364,757698,757775-757776,757814,757854,757856,757862,758193,758263,758265,758349,758354,758629,758632,758634-758636,758639-758642,758646,758649,758653-758654,759880,759889,760386,760479,760945,761267,761279-761280,761282-761283,761292,761634,761645,761690-761691,761715,762671,762675,762700,762702,762731,762737,762755,762780-762781,762789,762793,762797,762802,762804,762808,762813-762814,762817-762818,762821-762823,763146,763160,763188,763205,763215,763242,763244,763248,763617,765322,765328,765337,765532,765551,765554,765556,765585

Modified: jackrabbit/branches/1.5/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/Text.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/Text.java?rev=767511&r1=767510&r2=767511&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/Text.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/Text.java Wed Apr 22 13:25:56 2009
@@ -16,8 +16,8 @@
  */
 package org.apache.jackrabbit.util;
 
-import java.io.UnsupportedEncodingException;
 import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
@@ -393,34 +393,35 @@
      * @param escape the escape character
      * @return the decoded string
      * @throws NullPointerException           if <code>string</code> is <code>null</code>.
-     * @throws ArrayIndexOutOfBoundsException if not enough character follow an
-     *                                        escape character
      * @throws IllegalArgumentException       if the 2 characters following the escape
-     *                                        character do not represent a hex-number.
+     *                                        character do not represent a hex-number
+     *                                        or if not enough characters follow an
+     *                                        escape character
      */
-    public static String unescape(String string, char escape) {
-        ByteArrayOutputStream out = new ByteArrayOutputStream(string.length());
-        for (int i = 0; i < string.length(); i++) {
-            char c = string.charAt(i);
-            if (c != escape) {
-                out.write(c);
-            } else if (i + 2 < string.length()) {
-                try {
-                    out.write(Integer.parseInt(string.substring(i + 1, i + 3), 16));
-                } catch (NumberFormatException e) {
-                    throw new IllegalArgumentException(
-                            "Escape sequence is not hexadecimal: " + string);
+    public static String unescape(String string, char escape)  {
+        try {
+            byte[] utf8 = string.getBytes("utf-8");
+
+            // Check whether escape occurs at invalid position
+            if ((utf8.length >= 1 && utf8[utf8.length - 1] == escape) ||
+                (utf8.length >= 2 && utf8[utf8.length - 2] == escape)) {
+                throw new IllegalArgumentException("Premature end of escape sequence at end of input");
+            }
+
+            ByteArrayOutputStream out = new ByteArrayOutputStream(utf8.length);
+            for (int k = 0; k < utf8.length; k++) {
+                byte b = utf8[k];
+                if (b == escape) {
+                    out.write((decodeDigit(utf8[++k]) << 4) + decodeDigit(utf8[++k]));
+                }
+                else {
+                    out.write(b);
                 }
-                i += 2;
-            } else {
-                throw new IllegalArgumentException(
-                        "Escape sequence is too short: " + string);
             }
-        }
 
-        try {
             return new String(out.toByteArray(), "utf-8");
-        } catch (UnsupportedEncodingException e) {
+        }
+        catch (UnsupportedEncodingException e) {
             throw new InternalError(e.toString());
         }
     }
@@ -483,26 +484,27 @@
     }
     
     /** Escapes all illegal XPath search characters of a string.
-    * <p>Example:<br>
-    * A search string like 'test?' will run into a ParseException
-    * documented in http://issues.apache.org/jira/browse/JCR-1248
-    * 
-    * @param string the string to encode
-    * @return the escaped string    
-    */
-   public static String escapeIllegalXpathSearchChars(String s) {
-       StringBuffer sb = new StringBuffer();
-       sb.append(s.substring(0, (s.length() - 1)));
-       char c = s.charAt(s.length() - 1);
-       // NOTE: keep this in sync with _ESCAPED_CHAR below!
-       if (c == '!' || c == '(' || c == ':' || c == '^' 
-           || c == '[' || c == ']' || c == '\"' || c == '{' 
-           || c == '}' || c == '?') {
-           sb.append('\\');
-       }
-       sb.append(c);
-       return sb.toString();
-   }
+     * <p>Example:<br>
+     * A search string like 'test?' will run into a ParseException
+     * documented in http://issues.apache.org/jira/browse/JCR-1248
+     *
+     * @param s the string to encode
+     * @return the escaped string
+     */
+    public static String escapeIllegalXpathSearchChars(String s) {
+        StringBuffer sb = new StringBuffer();
+        sb.append(s.substring(0, (s.length() - 1)));
+        char c = s.charAt(s.length() - 1);
+        // NOTE: keep this in sync with _ESCAPED_CHAR below!
+        if (c == '!' || c == '(' || c == ':' || c == '^'
+            || c == '[' || c == ']' || c == '\"' || c == '{'
+            || c == '}' || c == '?') {
+            sb.append('\\');
+        }
+        sb.append(c);
+        return sb.toString();
+    }
+
     /**
      * Unescapes previously escaped jcr chars.
      * <p/>
@@ -555,7 +557,7 @@
      */
     public static String getName(String path, char delim) {
         return path == null
-                ? null 
+                ? null
                 : path.substring(path.lastIndexOf(delim) + 1);
     }
 
@@ -763,4 +765,19 @@
         return result.toString();
     }
 
+    private static byte decodeDigit(byte b) {
+        if (b >= 0x30 && b <= 0x39) {
+            return (byte) (b - 0x30);
+        }
+        else if (b >= 0x41 && b <= 0x46) {
+            return (byte) (b - 0x37);
+        }
+        else if (b >= 0x61 && b <= 0x66) {
+            return (byte) (b - 0x57);
+        }
+        else {
+            throw new IllegalArgumentException("Escape sequence is not hexadecimal: " + (char)b);
+        }
+    }
+
 }

Modified: jackrabbit/branches/1.5/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/value/ValueHelper.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/value/ValueHelper.java?rev=767511&r1=767510&r2=767511&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/value/ValueHelper.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/value/ValueHelper.java Wed Apr 22 13:25:56 2009
@@ -35,6 +35,8 @@
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.FilterInputStream;
+import java.io.OutputStream;
+import java.io.BufferedOutputStream;
 
 /**
  * The <code>ValueHelper</code> class provides several <code>Value</code>
@@ -754,7 +756,7 @@
             // decode to temp file
             TransientFileFactory fileFactory = TransientFileFactory.getInstance();
             final File tmpFile = fileFactory.createTransientFile("bin", null, null);
-            FileOutputStream out = new FileOutputStream(tmpFile);
+            OutputStream out = new BufferedOutputStream(new FileOutputStream(tmpFile));
             try {
                 Base64.decode(reader, out);
             } finally {

Modified: jackrabbit/branches/1.5/jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/util/TextTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/util/TextTest.java?rev=767511&r1=767510&r2=767511&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/util/TextTest.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/util/TextTest.java Wed Apr 22 13:25:56 2009
@@ -16,14 +16,15 @@
  */
 package org.apache.jackrabbit.util;
 
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
 import junit.framework.TestCase;
+
 import org.apache.jackrabbit.name.IllegalNameException;
 import org.apache.jackrabbit.name.NameFormat;
 
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Iterator;
-
 /**
  * Test cases for the Text utility class.
  */
@@ -144,18 +145,46 @@
         }
     }
 
+    public void testUrlEscape() {
+        String testString = "\u4e2d\u56fd\u7684\u7f51\u9875 $% \u20acuro %$ ";
+
+        String escaped = testString
+            .replaceAll("%", "%25")
+            .replaceAll(" ", "%20");
+        String unescaped = Text.unescape(escaped);
+        assertEquals(testString, unescaped);
+
+        escaped = Text.escape(testString);
+        unescaped = Text.unescape(escaped);
+        assertEquals(testString, unescaped);
+
+        assertEquals("%", Text.unescape("%25"));
+        assertEquals("", Text.unescape(""));
+        assertEquals("\u4e2d\u56fd\u7684\u7f51\u9875", Text.unescape("\u4e2d\u56fd\u7684\u7f51\u9875"));
+    }
+
     /**
      * @see <a href="https://issues.apache.org/jira/browse/JCR-1926">JCR-1926</a>
      */
     public void testUnescapeWithInvalidInput() {
         assertInvalidUnescape("%");   // too short
+        assertInvalidUnescape("anything%");   // too short
         assertInvalidUnescape("%%");  // too short
+        assertInvalidUnescape("anything%%");  // too short
+        assertInvalidUnescape("%1");  // too short
+        assertInvalidUnescape("anything%1");  // too short
         assertInvalidUnescape("%%%"); // not a number
+        assertInvalidUnescape("%ag"); // not a number
+        assertInvalidUnescape("anything%%%"); // not a number
+        assertInvalidUnescape("anything%ag"); // not a number
+        assertInvalidUnescape("anything%%%anything"); // not a number
+        assertInvalidUnescape("anything%aganything"); // not a number
     }
 
     private void assertInvalidUnescape(String string) {
         try {
             Text.unescape(string);
+            fail("Text.unescape(" + string + ") should throw IllegalArgumentException");
         } catch (IllegalArgumentException expected) {
         } catch (RuntimeException unexpected) {
             fail("Text.unescape(" + string + "): " + unexpected.getMessage());