Enforce a line limit of 50,000 for pretty file formatting. Files with large number of lines are treated as raw. Change-Id: Id793e6b09033c8c625cb1004c937f5a46fbc7a93
diff --git a/java/com/google/gitiles/BlobSoyData.java b/java/com/google/gitiles/BlobSoyData.java index c505ed4..f1710d1 100644 --- a/java/com/google/gitiles/BlobSoyData.java +++ b/java/com/google/gitiles/BlobSoyData.java
@@ -49,6 +49,13 @@ */ private static final int MAX_FILE_SIZE = 10 << 20; + /** + * Maximum number of lines to be displayed. Files larger than this will be displayed as binary + * files, even on a text content. For example really big XML files may be above this limit and + * will get displayed as binary. + */ + private static final int MAX_LINE_COUNT = 50000; + private final GitilesView view; private final ObjectReader reader; @@ -71,6 +78,9 @@ try { byte[] raw = loader.getCachedBytes(MAX_FILE_SIZE); content = !RawText.isBinary(raw) ? RawParseUtils.decode(raw) : null; + if (isContentTooLargeForDisplay(content)) { + content = null; + } } catch (LargeObjectException.OutOfMemory e) { throw e; } catch (LargeObjectException e) { @@ -188,4 +198,21 @@ return ext; } } + + private static boolean isContentTooLargeForDisplay(String content) { + if (content == null) { + return false; + } + + int lines = 0; + int nl = -1; + while (true) { + nl = nextLineBreak(content, nl + 1, content.length()); + if (nl < 0) { + return false; + } else if (++lines == MAX_LINE_COUNT) { + return true; + } + } + } }
diff --git a/javatests/com/google/gitiles/PathServletTest.java b/javatests/com/google/gitiles/PathServletTest.java index c0f98b1..c8ab575 100644 --- a/javatests/com/google/gitiles/PathServletTest.java +++ b/javatests/com/google/gitiles/PathServletTest.java
@@ -102,6 +102,34 @@ } @Test + public void fileWithMaxLines() throws Exception { + int MAX_LINE_COUNT = 50000; + StringBuilder contentBuilder = new StringBuilder(); + for (int i = 1; i < MAX_LINE_COUNT; i++) { + contentBuilder.append("\n"); + } + repo.branch("master").commit().add("bar", contentBuilder.toString()).create(); + + Map<String, ?> data = buildData("/repo/+/master/bar"); + SoyListData lines = (SoyListData) getBlobData(data).get("lines"); + assertThat(lines.length()).isEqualTo(MAX_LINE_COUNT - 1); + } + + @Test + public void fileLargerThanSupportedLines() throws Exception { + int MAX_LINE_COUNT = 50000; + StringBuilder contentBuilder = new StringBuilder(); + for (int i = 1; i <= MAX_LINE_COUNT; i++) { + contentBuilder.append("\n"); + } + repo.branch("master").commit().add("largebar", contentBuilder.toString()).create(); + + Map<String, ?> data = buildData("/repo/+/master/largebar"); + SoyListData lines = (SoyListData) getBlobData(data).get("lines"); + assertThat(lines).isNull(); + } + + @Test public void symlinkHtml() throws Exception { final RevBlob link = repo.blob("foo"); repo.branch("master")