Skip to content

Commit

Permalink
Bug 569665 Enable parsing of compressed files created by OpenJDK >= 15
Browse files Browse the repository at this point in the history
Improved CRC processing for old Gzip reader.
Tidy up help for acquire dialogs.

Change-Id: I8136f69264c421450fa05409d4a1b92cbde7573e
Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=569665
  • Loading branch information
ajohnson1 committed Apr 19, 2021
1 parent ed358ff commit 8098214
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -549,8 +549,8 @@ public ChunkedGZIPOutputStream(OutputStream os, File originalFile)
defaultHeader[5] = (byte)(lastMod >> 8);
defaultHeader[6] = (byte)(lastMod >> 16);
defaultHeader[7] = (byte)(lastMod >> 24);
String opsys = System.getProperty("os.name").toLowerCase(Locale.ENGLISH); //$NON-NLS-1$
if (opsys.contains("linux") || opsys.contains("unix")) //$NON-NLS-1$ //$NON-NLS-2$
String opsys = System.getProperty("os.name").toLowerCase(Locale.ROOT); //$NON-NLS-1$
if (opsys.contains("linux") || opsys.contains("unix") || opsys.contains("aix")) //$NON-NLS-1$ //$NON-NLS-2$
defaultHeader[9] = 3;
else if (opsys.contains("mac")) //$NON-NLS-1$
defaultHeader[9] = 7;
Expand Down Expand Up @@ -656,6 +656,9 @@ public void close() throws IOException
{
try
{
// for zero length files we still want to generate a gzip
if (!writtenComment)
header();
flush();
def.finish();
dos.close();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/*******************************************************************************
* Copyright (c) 2019,2020 IBM Corporation.
* Copyright (c) 2019,2021 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
Expand Down Expand Up @@ -223,6 +223,12 @@ static long estimatedLength(RandomAccessFile ra) throws IOException
best = e2;
if (e3 >= 0 && Math.abs(e3 - estimate) < Math.abs(best - estimate))
best = e3;
/*
* Attempt to detect a chunked file and round up the size
* to at least 4GB so the parser doesn't throw an error with an inaccurate size
*/
if (best < 0x100000000L && len32 <= 1024 * 1024)
best = 0x100000000L;
return best;
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.zip.CRC32;
import java.util.zip.ZipException;

import io.nayuki.deflate.InflaterInputStream;
Expand All @@ -37,26 +36,25 @@ public class GZIPInputStream2 extends FilterInputStream
InputStream is;
long uncompressedLen;
long uncompressedLocationAtHeader;
CRC32 crc = new CRC32();
CRC32 crc;
boolean checkcrc;
String comment;
String filename;
public GZIPInputStream2(GZIPInputStream2 gs) throws IOException
{
super(new InflaterInputStream((InflaterInputStream)gs.in));
is = gs.is;
crc = gs.crc.clone();
uncompressedLen = gs.uncompressedLen;
uncompressedLocationAtHeader = gs.uncompressedLocationAtHeader;
// FIXME Need to initialize CRC to other value, so until then disable the CRC check
checkcrc = false;
}

public GZIPInputStream2(InputStream is) throws IOException
{
super(new InflaterInputStream(is, false));
this.is = is;
crc = new CRC32();
readHeader(is);
checkcrc = true;
}

private InputStream readHeader(InputStream is) throws IOException
Expand Down Expand Up @@ -85,6 +83,8 @@ private InputStream readHeader(InputStream is, int b0) throws IOException
if (b3 < 0)
throw new ZipException(Messages.GZIPInputStream2_TruncatedHeader);
crc.update(b3);
if ((b3 & 0xe0) != 0x0)
throw new ZipException(Messages.GZIPInputStream2_BadHeaderFlag);
int b4 = is.read();
if (b4 < 0)
throw new ZipException(Messages.GZIPInputStream2_TruncatedHeader);
Expand Down Expand Up @@ -143,21 +143,21 @@ private InputStream readHeader(InputStream is, int b0) throws IOException
bos.write(b);
}
crc.update(0);
filename = new String(bos.toByteArray(), StandardCharsets.UTF_8);
filename = new String(bos.toByteArray(), StandardCharsets.ISO_8859_1);
}
// Comment
if ((b3 & FLG_FCOMMENT) != 0)
{
int b;
StringBuilder sb = new StringBuilder();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((b = is.read()) != 0) {
if (b == -1)
throw new ZipException(Messages.GZIPInputStream2_TruncatedComment);
crc.update(b);
sb.append((char)b);
bos.write(b);
}
crc.update(0);
comment = sb.toString();
comment = new String(bos.toByteArray(), StandardCharsets.ISO_8859_1);
}
// CRC16
if ((b3 & FLG_FHCRC) != 0)
Expand Down Expand Up @@ -197,7 +197,7 @@ public int read() throws IOException
((InflaterInputStream)in).attach();
}
} while (r < 0);
if (r >= 0);
if (r >= 0)
{
crc.update(r);
++uncompressedLen;
Expand Down Expand Up @@ -274,7 +274,7 @@ void checkTrailer(InputStream is) throws IOException
// Unsigned
long crc32 = b0 & 0xff | (b1 & 0xff) << 8 | (b2 & 0xff) << 16 | (b3 & 0xffL) << 24;
long crc32v = crc.getValue();
if (checkcrc && crc32v != crc32)
if (crc32v != crc32)
throw new ZipException(Messages.GZIPInputStream2_BadTrailerCRC);
// uncompressed length
int b4 = is.read();
Expand Down Expand Up @@ -305,4 +305,63 @@ public void close() throws IOException
{
super.close();
}

/**
* A CRC32 implementation - which
* allows the state to be cloned.
*/
private static class CRC32 implements Cloneable
{
int value;
private static final int table[] = new int[256];
static
{
for (int i = 0; i < 256; ++i)
{
int v = i;
for (int j = 0; j < 8; ++j)
{
if ((v & 1) != 0)
v = 0xedb88320 ^ (v >>> 1);
else
v >>>= 1;
}
table[i] = v;
}
}
public CRC32()
{
reset();
}
@Override
public CRC32 clone()
{
CRC32 c = new CRC32();
c.value = value;
return c;
}
public void reset()
{
value = 0xffffffff;
}
public void update(int b)
{
value = table[(value ^ (b & 0xff)) & 0xff] ^ (value >>> 8);
}
public void update(byte b[], int offset, int len)
{
for (int i = 0; i < len; ++i)
{
update(b[offset + i]);
}
}
public void update(byte b[])
{
update(b, 0, b.length);
}
public long getValue()
{
return (value ^ 0xffffffff) & 0xffffffffL;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/*******************************************************************************
* Copyright (c) 2010, 2020 SAP AG and others.
* Copyright (c) 2010, 2021 SAP AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
Expand Down Expand Up @@ -41,6 +41,7 @@ public class Messages extends NLS
public static String ExportHprof_SegmentSizeMismatch;
public static String ExportHprof_SegmentTooLong;
public static String GZIPInputStream2_BadHeaderCRC;
public static String GZIPInputStream2_BadHeaderFlag;
public static String GZIPInputStream2_BadTrailerCRC;
public static String GZIPInputStream2_BadTrailerLength;
public static String GZIPInputStream2_NotAGzip;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ ExportHprof_RemapProperties=Eclipse Memory Analyzer remap file version 1.0. Dump
ExportHprof_SegmentSizeMismatch=Heap dump segment {0} expected size {1} actual size {2} at 0x{3}
ExportHprof_SegmentTooLong=Heap dump segment {0} at 0x{1} is too long: {2}, continuing...
GZIPInputStream2_BadHeaderCRC=Bad header CRC
GZIPInputStream2_BadHeaderFlag=Bad header flag
GZIPInputStream2_BadTrailerCRC=Bad CRC trailer
GZIPInputStream2_BadTrailerLength=bad length
GZIPInputStream2_NotAGzip=Not a Gzip
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,7 @@ public void keyPressed(KeyEvent e)
tableComposite.layout();
tableComposite.pack();

Control control = localVMsTable.getParent();
PlatformUI.getWorkbench().getHelpSystem().setHelp(control, "org.eclipse.mat.ui.help.acquire_arguments"); //$NON-NLS-1$
PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, "org.eclipse.mat.ui.help.acquire_arguments"); //$NON-NLS-1$

italicFont = resourceManager.createFont(FontDescriptor.createFrom(column.getParent().getFont()).setStyle(SWT.ITALIC));

Expand Down Expand Up @@ -583,6 +582,21 @@ private void selectionChanged()
getContainer().updateButtons();
}

@Override
public void performHelp()
{
if (localVMsTable.getSelectionIndex() >= 0)
{
AnnotatedObjectArgumentsSet argumentsSet = (AnnotatedObjectArgumentsSet) localVMsTable.getSelection()[0].getData();
String helpUrl = argumentsSet.getDescriptor().getHelpUrl();
if (helpUrl != null)
{
PlatformUI.getWorkbench().getHelpSystem().displayHelpResource(helpUrl);
}
}
PlatformUI.getWorkbench().getHelpSystem().displayHelp("org.eclipse.mat.ui.help.acquire_arguments"); //$NON-NLS-1$
}

private static class GetVMListRunnable implements IRunnableWithProgress
{
private IStatus status;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public void createControl(Composite parent)
tableComposite.layout();
tableComposite.pack();

//PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, "org.eclipse.mat.ui.help.acquire_arguments"); //$NON-NLS-1$
PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, "org.eclipse.mat.ui.help.acquire_arguments"); //$NON-NLS-1$
composite.setContent(tableComposite);
setControl(composite);

Expand All @@ -93,7 +93,7 @@ public void handleEvent(Event event)
if (isCurrentPage())
{
IPreferenceStore prefs = MemoryAnalyserPlugin.getDefault().getPreferenceStore();
if (!prefs.getBoolean(HIDE_QUERY_HELP))
if (!prefs.getBoolean(HIDE_QUERY_HELP) || helpPopup != null && helpPopup.getShell() != null)
{
relocateHelp(true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public void widgetSelected(SelectionEvent e)
table.providerSelected(argumentsSet);
onFocus(null);
IPreferenceStore prefs = MemoryAnalyserPlugin.getDefault().getPreferenceStore();
if (!prefs.getBoolean(HIDE_QUERY_HELP))
if (!prefs.getBoolean(HIDE_QUERY_HELP) || helpPopup != null && helpPopup.getShell() != null)
{
relocateHelp(true);
}
Expand All @@ -124,7 +124,7 @@ public void widgetSelected(SelectionEvent e)
// If a process is selected, make the configuration provider match the process
acquireDialog.addProcessSelectionListener(this);

//PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, "org.eclipse.mat.ui.help.query_arguments"); //$NON-NLS-1$
PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, "org.eclipse.mat.ui.help.acquire_arguments"); //$NON-NLS-1$

Listener listener = new Listener()
{
Expand Down

0 comments on commit 8098214

Please sign in to comment.