Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WICKET-6993 - Resource Variations containing a single character are not correctly decoded #529

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
WICKET-6993 - Add new escape methods
We prepare the refactor of the resource encoding by
adding new methods for encoding and decoding the parts
of an resource
  • Loading branch information
Peter Lamby committed Jul 4, 2022
commit 0246fa059f483fdf62f7dabbd86a16a77220132e
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Locale;
import java.util.regex.Pattern;

Expand All @@ -39,6 +40,10 @@
public class ResourceUtil
{

/**
* Used to denote {@code null} in encoded strings.
*/
private static final String NULL_VALUE = "null";
private static final Pattern ESCAPED_ATTRIBUTE_PATTERN = Pattern.compile("(\\w)~(\\w)");

/**
Expand Down Expand Up @@ -281,6 +286,62 @@ public static String unescapeAttributesSeparator(String attribute)
return Strings.replaceAll(tmp, "~~", "~").toString();
}

/**
* Encode the {@code part} in the format <string length encoded in base ten ASCII>~<string data>.
*
* If the {@code part} is {@code null} the special value {@link #NULL_VALUE} is returned;
*
* @param part
* The string to encode
* @return The encoded string
*/
static String encodeStringPart(String part)
{
if (part == null) {
return NULL_VALUE;
}

int length = part.length();
return length + "~" + part;
}

/**
* Decodes the {@code encoded} parts of a string decoded by {@link #encodeStringPart(String)}.
*
* @param encoded
* @return An array containing the parts of {@code encoded}.
* The array can contain {@code null} but is itself never {@code null}
*/
static String[] decodeStringParts(String encoded)
{
ArrayList<String> result = new ArrayList<>();

StringBuilder lengthString = new StringBuilder();
char[] chars = encoded.toCharArray();
for (int i = 0; i < chars.length; i++)
{
boolean isAtStartOfPart = lengthString.length() == 0;
if (isAtStartOfPart && chars.length >= i + NULL_VALUE.length() &&
String.valueOf(chars, i, NULL_VALUE.length()).equals(NULL_VALUE)) {
result.add(null);
i += NULL_VALUE.length() - 1;
continue;
}

char c = chars[i];
if (c >= '0' && c <= '9') {
lengthString.append(c);
} else {
int length = Integer.parseInt(lengthString.toString());
lengthString.setLength(0); // reset the length buffer
result.add(String.valueOf(chars, i + 1, length));
i += length;
}
}

return result.toArray(String[]::new);
}

private ResourceUtil()
{
// no-op
Expand Down