SHA256
Сократить служебные теги SHiNE и сохранить обратную совместимость
This commit is contained in:
+21
-5
@@ -6,6 +6,8 @@ import java.util.Map;
|
||||
public final class ChannelMetaTextParser {
|
||||
public static final int MAX_TITLE_CHARS = 50;
|
||||
public static final int MAX_DESCRIPTION_CHARS = 250;
|
||||
private static final String LEGACY_PREFIX = "<SHiNE:";
|
||||
private static final String SHORT_PREFIX = "<S:";
|
||||
|
||||
private ChannelMetaTextParser() {}
|
||||
|
||||
@@ -19,15 +21,16 @@ public final class ChannelMetaTextParser {
|
||||
boolean seenAvatar = false;
|
||||
|
||||
int offset = 0;
|
||||
while (text.startsWith("<SHiNE:", offset)) {
|
||||
while (startsWithTagPrefix(text, offset)) {
|
||||
int end = text.indexOf('>', offset);
|
||||
if (end < 0) throw new IllegalArgumentException("bad_channel_meta_tag");
|
||||
String body = text.substring(offset + "<SHiNE:".length(), end);
|
||||
int prefixLength = tagPrefixLength(text, offset);
|
||||
String body = text.substring(offset + prefixLength, end);
|
||||
if (body.startsWith("title;")) {
|
||||
if (seenTitle) throw new IllegalArgumentException("duplicate_channel_meta_title");
|
||||
seenTitle = true;
|
||||
title = parseTitleTag(body);
|
||||
} else if (body.startsWith("avatar;")) {
|
||||
} else if (body.startsWith("avatar;") || body.startsWith("ava;")) {
|
||||
if (seenAvatar) throw new IllegalArgumentException("duplicate_channel_meta_avatar");
|
||||
seenAvatar = true;
|
||||
Avatar avatar = parseAvatarTag(body);
|
||||
@@ -61,11 +64,14 @@ public final class ChannelMetaTextParser {
|
||||
}
|
||||
|
||||
private static Avatar parseAvatarTag(String body) {
|
||||
Map<String, String> fields = parseFields(body.substring("avatar;".length()));
|
||||
String rawFields = body.startsWith("ava;")
|
||||
? body.substring("ava;".length())
|
||||
: body.substring("avatar;".length());
|
||||
Map<String, String> fields = parseFields(rawFields);
|
||||
if (!"1".equals(fields.get("v"))) throw new IllegalArgumentException("bad_channel_meta_avatar_version");
|
||||
String ar = String.valueOf(fields.getOrDefault("ar", "")).trim();
|
||||
String sha256 = String.valueOf(fields.getOrDefault("sha256", "")).trim().toLowerCase();
|
||||
String sizeRaw = String.valueOf(fields.getOrDefault("size", "")).trim();
|
||||
String sizeRaw = String.valueOf(fields.containsKey("sz") ? fields.get("sz") : fields.getOrDefault("size", "")).trim();
|
||||
if (!ar.matches("^[A-Za-z0-9_-]{43}$")) throw new IllegalArgumentException("bad_channel_meta_avatar_ar");
|
||||
if (!sha256.matches("^[0-9a-f]{64}$")) throw new IllegalArgumentException("bad_channel_meta_avatar_sha256");
|
||||
long size;
|
||||
@@ -78,6 +84,16 @@ public final class ChannelMetaTextParser {
|
||||
return new Avatar(ar, sha256, size);
|
||||
}
|
||||
|
||||
private static boolean startsWithTagPrefix(String text, int offset) {
|
||||
return text.startsWith(LEGACY_PREFIX, offset) || text.startsWith(SHORT_PREFIX, offset);
|
||||
}
|
||||
|
||||
private static int tagPrefixLength(String text, int offset) {
|
||||
if (text.startsWith(LEGACY_PREFIX, offset)) return LEGACY_PREFIX.length();
|
||||
if (text.startsWith(SHORT_PREFIX, offset)) return SHORT_PREFIX.length();
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static Map<String, String> parseFields(String raw) {
|
||||
Map<String, String> out = new HashMap<>();
|
||||
for (String part : String.valueOf(raw == null ? "" : raw).split(";")) {
|
||||
|
||||
Reference in New Issue
Block a user