You've already forked Arcturus-Morningstar-Extended
mirror of
https://github.com/duckietm/Arcturus-Morningstar-Extended.git
synced 2026-06-20 07:26:18 +00:00
fix(items): guard oversized manifest NPE in FurnidataReader + document JSON5 trailing-comma limit
This commit is contained in:
@@ -85,7 +85,9 @@ public class FurnidataReader {
|
|||||||
Path m = dir.resolve(name);
|
Path m = dir.resolve(name);
|
||||||
if (!Files.exists(m)) continue;
|
if (!Files.exists(m)) continue;
|
||||||
try {
|
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()) {
|
if (obj.has(key) && obj.get(key).isJsonArray()) {
|
||||||
List<String> list = new ArrayList<>();
|
List<String> list = new ArrayList<>();
|
||||||
for (JsonElement el : obj.getAsJsonArray(key)) list.add(el.getAsString());
|
for (JsonElement el : obj.getAsJsonArray(key)) list.add(el.getAsString());
|
||||||
@@ -133,7 +135,13 @@ public class FurnidataReader {
|
|||||||
return candidate.toAbsolutePath().normalize().startsWith(baseNorm);
|
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) {
|
static String stripJson5(String content) {
|
||||||
if (content == null || content.isEmpty()) return content;
|
if (content == null || content.isEmpty()) return content;
|
||||||
StringBuilder out = new StringBuilder(content.length());
|
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
|
@Test
|
||||||
void splitDirRejectsTraversalFiles(@TempDir Path dir) throws Exception {
|
void splitDirRejectsTraversalFiles(@TempDir Path dir) throws Exception {
|
||||||
Path secret = dir.resolve("secret.json");
|
Path secret = dir.resolve("secret.json");
|
||||||
|
|||||||
Reference in New Issue
Block a user