Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,10 @@ private static Object commandCallback(Object proxy, Method method, Object[] argu
private static void sendMessage(Object player, String message) throws ReflectiveOperationException {
ClassLoader loader = player.getClass().getClassLoader();
Class<?> componentType = Class.forName("net.minecraft.network.chat.Component", false, loader);
Object component = componentType.getMethod("literal", String.class).invoke(null, message);
// This is a native literal component: all replacement and validation has
// already finished, so discard guards only at the final display sink.
Object component = componentType.getMethod("literal", String.class)
.invoke(null, com.bencodez.votingplugin.util.ServiceSiteValidator.literalAfterFormatting(message));
Method send = findAssignableMethod(player.getClass(), "sendSystemMessage", componentType);
invokeMessage(player, send, component);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ public static String inertForFormatting(String value) {
return inert.append(FORMATTING_BOUNDARY).toString();
}

/**
* Restores the literal display value after all placeholder and formatting
* parsers have run. Do not call this on an intermediate template: it would
* allow untrusted identifiers to complete formatting tokens again.
*/
public static String literalAfterFormatting(String value) {
return value == null ? null : value.replace(FORMATTING_BOUNDARY, "");
}

private static boolean isDisallowed(int codePoint) {
if (codePoint == '[' || codePoint == ']' || codePoint == '\'' || codePoint == '"' || codePoint == '`'
|| codePoint == '\u00A7'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ void formattingGuardPreventsTokensAcrossTemplateBoundaries() {
assertEquals(value, guarded.replace("\u2060", ""));
}

@Test
void finalLiteralMessageRemovesAllFormattingGuards() {
for (String site : new String[] { "Minecraft Menu", "R&D", "&aGreen",
"%player_name%", "https://example.com/vote?id=1&source=proxy" }) {
String guarded = ServiceSiteValidator.inertForFormatting(site);
assertEquals(site, ServiceSiteValidator.literalAfterFormatting(guarded));
assertFalse(ServiceSiteValidator.literalAfterFormatting(guarded).contains("\u2060"));
}
}

@Test
void rejectsMissingAndOversizedNames() {
assertFalse(ServiceSiteValidator.isValid(null));
Expand Down
Loading