fix(items): guard oversized manifest NPE in FurnidataReader + document JSON5 trailing-comma limit

This commit is contained in:
simoleo89
2026-06-04 20:54:13 +02:00
parent 86498b6b4c
commit b162b3f4d8
2 changed files with 21 additions and 2 deletions
@@ -85,7 +85,9 @@ public class FurnidataReader {
Path m = dir.resolve(name);
if (!Files.exists(m)) continue;
try {
JsonObject obj = JsonParser.parseString(readJson5Capped(m)).getAsJsonObject();
String raw = readJson5Capped(m);
if (raw == null) continue;
JsonObject obj = JsonParser.parseString(raw).getAsJsonObject();
if (obj.has(key) && obj.get(key).isJsonArray()) {
List<String> list = new ArrayList<>();
for (JsonElement el : obj.getAsJsonArray(key)) list.add(el.getAsString());
@@ -133,7 +135,13 @@ public class FurnidataReader {
return candidate.toAbsolutePath().normalize().startsWith(baseNorm);
}
/** Strip // and block comments and trailing commas so Gson can parse JSON5. */
/**
* Strip // and block comments and trailing commas so Gson can parse JSON5.
* Known limitation: the trailing-comma pass is a regex over the whole output,
* so a string value literally containing ",[whitespace]}" or ",[whitespace]]"
* would be altered. Real Habbo furnidata names/descriptions do not contain
* that pattern; values are additionally sanitized downstream before use.
*/
static String stripJson5(String content) {
if (content == null || content.isEmpty()) return content;
StringBuilder out = new StringBuilder(content.length());
@@ -55,6 +55,17 @@ class FurnidataReaderTest {
});
}
@Test
void oversizedManifestIsSkippedNeverThrows(@TempDir Path dir) throws Exception {
Path base = dir.resolve("furnidata");
Path core = base.resolve("core");
Files.createDirectories(core);
// A root manifest larger than the cap we pass in.
Files.writeString(base.resolve("manifest.json"), "{ \"tiers\": [ \"core\" ] } // padding ".repeat(50));
List<FurnidataEntry> entries = new FurnidataReader(base, 8 /* bytes */).read();
assertTrue(entries.isEmpty());
}
@Test
void splitDirRejectsTraversalFiles(@TempDir Path dir) throws Exception {
Path secret = dir.resolve("secret.json");