@Test(expected = IllegalArgumentException.class) public void shouldFailIfPathSeparatorPresent() { uriPathPercentDecode("zy%2dggy/", false); }
@SuppressWarnings({"squid:S3776", "checkstyle:magicnumber"}) public static String uriPathPercentDecode(final String src, final boolean allowSeparator) { final int length = src.length(); if (length == 0) { return src; } final byte[] buf = new byte[length]; boolean changed = false; int i = 0; int pos = 0; while (i < length) { char ch = src.charAt(i); if (ch == '/' && allowSeparator) { buf[pos++] = (byte)ch; i++; } else if (ch == '%') { if (i + 2 >= length) { throw new IllegalArgumentException("Incomplete percent encoding"); } final int d1 = hexdigit(src.charAt(i + 1)); final int d2 = hexdigit(src.charAt(i + 2)); if (d1 == -1 || d2 == -1) { throw new IllegalArgumentException("Invalid percent encoding"); } if (allowSeparator && d1 == 0x02 && d2 == 0x0D) { buf[pos++] = '%'; buf[pos++] = '2'; buf[pos++] = 'D'; } else { buf[pos++] = (byte)((d1 << 4) + d2); } i += 3; changed = true; } else if (safeChar(ch)) { buf[pos++] = (byte)ch; i++; } else { throw new IllegalArgumentException("Invalid character in path segment"); } } return (changed ? new String(buf, 0, pos, StandardCharsets.UTF_8) : src); }
UriUtils { @SuppressWarnings({"squid:S3776", "checkstyle:magicnumber"}) public static String uriPathPercentDecode(final String src, final boolean allowSeparator) { final int length = src.length(); if (length == 0) { return src; } final byte[] buf = new byte[length]; boolean changed = false; int i = 0; int pos = 0; while (i < length) { char ch = src.charAt(i); if (ch == '/' && allowSeparator) { buf[pos++] = (byte)ch; i++; } else if (ch == '%') { if (i + 2 >= length) { throw new IllegalArgumentException("Incomplete percent encoding"); } final int d1 = hexdigit(src.charAt(i + 1)); final int d2 = hexdigit(src.charAt(i + 2)); if (d1 == -1 || d2 == -1) { throw new IllegalArgumentException("Invalid percent encoding"); } if (allowSeparator && d1 == 0x02 && d2 == 0x0D) { buf[pos++] = '%'; buf[pos++] = '2'; buf[pos++] = 'D'; } else { buf[pos++] = (byte)((d1 << 4) + d2); } i += 3; changed = true; } else if (safeChar(ch)) { buf[pos++] = (byte)ch; i++; } else { throw new IllegalArgumentException("Invalid character in path segment"); } } return (changed ? new String(buf, 0, pos, StandardCharsets.UTF_8) : src); } }
UriUtils { @SuppressWarnings({"squid:S3776", "checkstyle:magicnumber"}) public static String uriPathPercentDecode(final String src, final boolean allowSeparator) { final int length = src.length(); if (length == 0) { return src; } final byte[] buf = new byte[length]; boolean changed = false; int i = 0; int pos = 0; while (i < length) { char ch = src.charAt(i); if (ch == '/' && allowSeparator) { buf[pos++] = (byte)ch; i++; } else if (ch == '%') { if (i + 2 >= length) { throw new IllegalArgumentException("Incomplete percent encoding"); } final int d1 = hexdigit(src.charAt(i + 1)); final int d2 = hexdigit(src.charAt(i + 2)); if (d1 == -1 || d2 == -1) { throw new IllegalArgumentException("Invalid percent encoding"); } if (allowSeparator && d1 == 0x02 && d2 == 0x0D) { buf[pos++] = '%'; buf[pos++] = '2'; buf[pos++] = 'D'; } else { buf[pos++] = (byte)((d1 << 4) + d2); } i += 3; changed = true; } else if (safeChar(ch)) { buf[pos++] = (byte)ch; i++; } else { throw new IllegalArgumentException("Invalid character in path segment"); } } return (changed ? new String(buf, 0, pos, StandardCharsets.UTF_8) : src); } private  UriUtils(); }
UriUtils { @SuppressWarnings({"squid:S3776", "checkstyle:magicnumber"}) public static String uriPathPercentDecode(final String src, final boolean allowSeparator) { final int length = src.length(); if (length == 0) { return src; } final byte[] buf = new byte[length]; boolean changed = false; int i = 0; int pos = 0; while (i < length) { char ch = src.charAt(i); if (ch == '/' && allowSeparator) { buf[pos++] = (byte)ch; i++; } else if (ch == '%') { if (i + 2 >= length) { throw new IllegalArgumentException("Incomplete percent encoding"); } final int d1 = hexdigit(src.charAt(i + 1)); final int d2 = hexdigit(src.charAt(i + 2)); if (d1 == -1 || d2 == -1) { throw new IllegalArgumentException("Invalid percent encoding"); } if (allowSeparator && d1 == 0x02 && d2 == 0x0D) { buf[pos++] = '%'; buf[pos++] = '2'; buf[pos++] = 'D'; } else { buf[pos++] = (byte)((d1 << 4) + d2); } i += 3; changed = true; } else if (safeChar(ch)) { buf[pos++] = (byte)ch; i++; } else { throw new IllegalArgumentException("Invalid character in path segment"); } } return (changed ? new String(buf, 0, pos, StandardCharsets.UTF_8) : src); } private  UriUtils(); static String uriSegmentPercentDecode(final String src); @SuppressWarnings({"squid:S3776", "checkstyle:magicnumber"}) static String uriPathPercentDecode(final String src, final boolean allowSeparator); }
UriUtils { @SuppressWarnings({"squid:S3776", "checkstyle:magicnumber"}) public static String uriPathPercentDecode(final String src, final boolean allowSeparator) { final int length = src.length(); if (length == 0) { return src; } final byte[] buf = new byte[length]; boolean changed = false; int i = 0; int pos = 0; while (i < length) { char ch = src.charAt(i); if (ch == '/' && allowSeparator) { buf[pos++] = (byte)ch; i++; } else if (ch == '%') { if (i + 2 >= length) { throw new IllegalArgumentException("Incomplete percent encoding"); } final int d1 = hexdigit(src.charAt(i + 1)); final int d2 = hexdigit(src.charAt(i + 2)); if (d1 == -1 || d2 == -1) { throw new IllegalArgumentException("Invalid percent encoding"); } if (allowSeparator && d1 == 0x02 && d2 == 0x0D) { buf[pos++] = '%'; buf[pos++] = '2'; buf[pos++] = 'D'; } else { buf[pos++] = (byte)((d1 << 4) + d2); } i += 3; changed = true; } else if (safeChar(ch)) { buf[pos++] = (byte)ch; i++; } else { throw new IllegalArgumentException("Invalid character in path segment"); } } return (changed ? new String(buf, 0, pos, StandardCharsets.UTF_8) : src); } private  UriUtils(); static String uriSegmentPercentDecode(final String src); @SuppressWarnings({"squid:S3776", "checkstyle:magicnumber"}) static String uriPathPercentDecode(final String src, final boolean allowSeparator);  }