Bug 569665 Enable parsing of compressed files created by OpenJDK >= 15
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
diff --git a/plugins/org.eclipse.mat.hprof/src/org/eclipse/mat/hprof/ChunkedGZIPRandomAccessFile.java b/plugins/org.eclipse.mat.hprof/src/org/eclipse/mat/hprof/ChunkedGZIPRandomAccessFile.java
index c86d506..e9a675c 100644
--- a/plugins/org.eclipse.mat.hprof/src/org/eclipse/mat/hprof/ChunkedGZIPRandomAccessFile.java
+++ b/plugins/org.eclipse.mat.hprof/src/org/eclipse/mat/hprof/ChunkedGZIPRandomAccessFile.java
@@ -549,8 +549,8 @@
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;
@@ -656,6 +656,9 @@
{
try
{
+ // for zero length files we still want to generate a gzip
+ if (!writtenComment)
+ header();
flush();
def.finish();
dos.close();
diff --git a/plugins/org.eclipse.mat.hprof/src/org/eclipse/mat/hprof/CompressedRandomAccessFile.java b/plugins/org.eclipse.mat.hprof/src/org/eclipse/mat/hprof/CompressedRandomAccessFile.java
index f65e032..f1b8469 100644
--- a/plugins/org.eclipse.mat.hprof/src/org/eclipse/mat/hprof/CompressedRandomAccessFile.java
+++ b/plugins/org.eclipse.mat.hprof/src/org/eclipse/mat/hprof/CompressedRandomAccessFile.java
@@ -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:
@@ -223,6 +223,12 @@
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
diff --git a/plugins/org.eclipse.mat.hprof/src/org/eclipse/mat/hprof/GZIPInputStream2.java b/plugins/org.eclipse.mat.hprof/src/org/eclipse/mat/hprof/GZIPInputStream2.java
index 3fbab83..782dade 100644
--- a/plugins/org.eclipse.mat.hprof/src/org/eclipse/mat/hprof/GZIPInputStream2.java
+++ b/plugins/org.eclipse.mat.hprof/src/org/eclipse/mat/hprof/GZIPInputStream2.java
@@ -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;
@@ -37,7 +36,7 @@
InputStream is;
long uncompressedLen;
long uncompressedLocationAtHeader;
- CRC32 crc = new CRC32();
+ CRC32 crc;
boolean checkcrc;
String comment;
String filename;
@@ -45,18 +44,17 @@
{
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
@@ -85,6 +83,8 @@
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);
@@ -143,21 +143,21 @@
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)
@@ -197,7 +197,7 @@
((InflaterInputStream)in).attach();
}
} while (r < 0);
- if (r >= 0);
+ if (r >= 0)
{
crc.update(r);
++uncompressedLen;
@@ -274,7 +274,7 @@
// 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();
@@ -305,4 +305,63 @@
{
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;
+ }
+ }
}
diff --git a/plugins/org.eclipse.mat.hprof/src/org/eclipse/mat/hprof/Messages.java b/plugins/org.eclipse.mat.hprof/src/org/eclipse/mat/hprof/Messages.java
index c4e600f..e2cf76b 100644
--- a/plugins/org.eclipse.mat.hprof/src/org/eclipse/mat/hprof/Messages.java
+++ b/plugins/org.eclipse.mat.hprof/src/org/eclipse/mat/hprof/Messages.java
@@ -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:
@@ -41,6 +41,7 @@
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;
diff --git a/plugins/org.eclipse.mat.hprof/src/org/eclipse/mat/hprof/messages.properties b/plugins/org.eclipse.mat.hprof/src/org/eclipse/mat/hprof/messages.properties
index 2381af1..faa87d1 100644
--- a/plugins/org.eclipse.mat.hprof/src/org/eclipse/mat/hprof/messages.properties
+++ b/plugins/org.eclipse.mat.hprof/src/org/eclipse/mat/hprof/messages.properties
@@ -35,6 +35,7 @@
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
diff --git a/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/internal/acquire/AcquireDialog.java b/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/internal/acquire/AcquireDialog.java
index 5dbe524..9b3957d 100644
--- a/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/internal/acquire/AcquireDialog.java
+++ b/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/internal/acquire/AcquireDialog.java
@@ -217,8 +217,7 @@
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));
@@ -583,6 +582,21 @@
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;
diff --git a/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/internal/acquire/ProviderArgumentsWizardPage.java b/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/internal/acquire/ProviderArgumentsWizardPage.java
index 5b050fb..3c2cf49 100644
--- a/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/internal/acquire/ProviderArgumentsWizardPage.java
+++ b/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/internal/acquire/ProviderArgumentsWizardPage.java
@@ -70,7 +70,7 @@
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);
@@ -93,7 +93,7 @@
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);
}
diff --git a/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/internal/acquire/ProviderConfigurationWizardPage.java b/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/internal/acquire/ProviderConfigurationWizardPage.java
index 9a60d90..c9c46a1 100644
--- a/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/internal/acquire/ProviderConfigurationWizardPage.java
+++ b/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/internal/acquire/ProviderConfigurationWizardPage.java
@@ -113,7 +113,7 @@
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);
}
@@ -124,7 +124,7 @@
// 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()
{