From 90c48c8f2afbbf252c3fe643c01580487fc5f14f Mon Sep 17 00:00:00 2001 From: Florian Angerer <florian.angerer@oracle.com> Date: Fri, 15 Dec 2017 11:27:17 +0100 Subject: [PATCH] Abort if a single line is too large. --- .../packages/analyzer/FileLineIterator.java | 73 ++++++++++++++++--- 1 file changed, 62 insertions(+), 11 deletions(-) diff --git a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/FileLineIterator.java b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/FileLineIterator.java index 9ad1f288a5..1dfd9ba956 100644 --- a/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/FileLineIterator.java +++ b/com.oracle.truffle.r.test.packages.analyzer/src/com/oracle/truffle/r/test/packages/analyzer/FileLineIterator.java @@ -24,25 +24,36 @@ package com.oracle.truffle.r.test.packages.analyzer; import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.nio.file.Files; import java.nio.file.Path; import java.util.NoSuchElementException; +import java.util.logging.Logger; public class FileLineIterator extends LineIterator { - /** Maximum number of lines that will be analyzed. */ - public static final int MAX_LINES = 500000; + private static final Logger LOGGER = Logger.getLogger(FileLineIterator.class.getName()); + + /** 100 MB */ + public static final int MAX_FILE_SIZE = 200 * 1024 * 1024; - private int cnt = 0; private BufferedReader reader; private String lookahead = null; public FileLineIterator(Path p) { try { - this.reader = Files.newBufferedReader(p); - nextLine(); + long size = Files.size(p); + if (size < MAX_FILE_SIZE) { + this.reader = Files.newBufferedReader(p); + nextLine(); + } else { + this.reader = new BufferedReader(new InputStreamReader(new LimitSizeInputStreamReader(Files.newInputStream(p), MAX_FILE_SIZE))); + LOGGER.warning(String.format("Will read at most %d bytes from file %s.", size, p)); + this.reader = null; + } } catch (IOException e) { - // ignore + LOGGER.severe(String.format("I/O error occurred when reading %s: %s", p, e.getMessage())); } } @@ -55,21 +66,21 @@ public class FileLineIterator extends LineIterator { private String nextLine() { - if (cnt++ >= MAX_LINES) { - return null; - } String line = lookahead; try { lookahead = reader.readLine(); + } catch (OutOfMemoryError e) { + // If a single line is just too large, abort. + lookahead = null; } catch (IOException e) { - + lookahead = null; } return line; } @Override public boolean hasNext() { - return cnt < MAX_LINES && lookahead != null; + return lookahead != null; } @Override @@ -79,4 +90,44 @@ public class FileLineIterator extends LineIterator { } throw new NoSuchElementException(); } + + private static class LimitSizeInputStreamReader extends InputStream { + + private final long limit; + private final InputStream source; + private long consumed; + + protected LimitSizeInputStreamReader(InputStream source, long limit) { + this.source = source; + this.limit = limit; + } + + @Override + public int read() throws IOException { + if (consumed < limit) { + consumed++; + return source.read(); + } + return -1; + } + + @Override + public int read(byte[] b) throws IOException { + return read(b, 0, b.length); + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + int read = super.read(b, off, (int) Math.min(limit - consumed, len)); + consumed += read; + return read; + } + + @Override + public int available() throws IOException { + return Math.min((int) (limit - consumed), super.available()); + } + + } + } -- GitLab