@@ -29,9 +29,10 @@ record Found(String world, int x, int y, int z) {}
2929 /** {@code complete} is false when some chunk could not be read, so a missing animal may still exist. */
3030 record Result (Map <UUID , Found > found , boolean complete ) {}
3131
32- private static final Pattern REGION = Pattern .compile ("r\\ .(-?\\ d+ )\\ .(-?\\ d+ )\\ .mca" );
32+ private static final Pattern REGION = Pattern .compile ("r\\ .(-?\\ d{1,7} )\\ .(-?\\ d{1,7} )\\ .mca" );
3333 private static final int SECTOR = 4096 ;
3434 private static final int MAX_CHUNK_BYTES = 32 * 1024 * 1024 ;
35+ private static final int MAX_REGION_BYTES = 256 * 1024 * 1024 ;
3536
3637 private HusbandryEntityScan () {}
3738
@@ -67,7 +68,7 @@ private static boolean scanRegion(
6768 WorldDir world , File file , int regionX , int regionZ , Set <UUID > targets , Map <UUID , Found > found ) {
6869 byte [] data ;
6970 try {
70- data = Files . readAllBytes (file . toPath () );
71+ data = readBounded (file , MAX_REGION_BYTES );
7172 } catch (IOException ex ) {
7273 return false ;
7374 }
@@ -108,7 +109,7 @@ private static byte[] chunkBytes(WorldDir world, byte[] data, int offset, int ch
108109 byte [] raw ;
109110 if ((compression & 0x80 ) != 0 ) {
110111 compression &= 0x7F ;
111- raw = Files . readAllBytes (new File (world .entities (), "c." + chunkX + "." + chunkZ + ".mcc" ). toPath () );
112+ raw = readBounded (new File (world .entities (), "c." + chunkX + "." + chunkZ + ".mcc" ), MAX_CHUNK_BYTES );
112113 } else {
113114 if (length < 1 || offset + 4 + length > data .length ) {
114115 return null ;
@@ -134,6 +135,16 @@ private static byte[] chunkBytes(WorldDir world, byte[] data, int offset, int ch
134135 }
135136 }
136137
138+ private static byte [] readBounded (File file , int max ) throws IOException {
139+ try (InputStream in = Files .newInputStream (file .toPath ())) {
140+ byte [] data = in .readNBytes (max + 1 );
141+ if (data .length > max ) {
142+ throw new IOException (file .getName () + " is larger than " + max + " bytes" );
143+ }
144+ return data ;
145+ }
146+ }
147+
137148 private static int readInt (byte [] data , int at ) {
138149 return ((data [at ] & 0xFF ) << 24 ) | ((data [at + 1 ] & 0xFF ) << 16 )
139150 | ((data [at + 2 ] & 0xFF ) << 8 ) | (data [at + 3 ] & 0xFF );
0 commit comments