(ExecutionContext context, String str, String reservedSet)
| 77 | } |
| 78 | |
| 79 | public static String decode(ExecutionContext context, String str, String reservedSet) { |
| 80 | |
| 81 | int len = str.length(); |
| 82 | StringBuilder r = new StringBuilder(); |
| 83 | |
| 84 | int k = 0; |
| 85 | |
| 86 | while (true) { |
| 87 | String s = null; |
| 88 | if (k == len) { |
| 89 | return r.toString(); |
| 90 | } |
| 91 | |
| 92 | char c = str.charAt(k); |
| 93 | |
| 94 | if (c != '%') { |
| 95 | s = "" + c; |
| 96 | } else { |
| 97 | int start = k; |
| 98 | if ((k + 2) >= len) { |
| 99 | throw new ThrowException(context, context.createUriError("invalid escape (not enough chars follow %)")); |
| 100 | } |
| 101 | if (!isHexDigit(str.charAt(k + 1)) || !isHexDigit(str.charAt(k + 2))) { |
| 102 | throw new ThrowException(context, context.createUriError("invalid escape (non-hex follow %)")); |
| 103 | } |
| 104 | int b = Integer.parseInt(str.substring(k + 1, k + 3), 16); |
| 105 | k = k + 2; |
| 106 | |
| 107 | if ((b & 0x80) == 0) { |
| 108 | String charStr = new String(new char[] { (char) b }); |
| 109 | |
| 110 | if (!reservedSet.contains(charStr)) { |
| 111 | s = charStr; |
| 112 | } else { |
| 113 | s = str.substring(start, k + 1); |
| 114 | } |
| 115 | } else { |
| 116 | int n = 1; |
| 117 | for (int nPos = 1; nPos < 8; ++nPos) { |
| 118 | if (((b << nPos) & 0x80) == 0) { |
| 119 | n = nPos; |
| 120 | break; |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | if (n == 1 || n > 4) { |
| 125 | throw new ThrowException(context, context.createUriError("invalid escape (too many hex sequences)")); |
| 126 | } |
| 127 | |
| 128 | int[] octets = new int[n]; |
| 129 | octets[0] = b; |
| 130 | |
| 131 | if ((k + (3 * (n - 1))) >= len) { |
| 132 | throw new ThrowException(context, context.createUriError("invalid escape (too many hex sequences)")); |
| 133 | } |
| 134 | |
| 135 | for (int j = 1; j < n; ++j) { |
| 136 | ++k; |
no test coverage detected