This is an automated email from the ASF dual-hosted git repository.
mbien pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/master by this push:
new a208c991c1 Defensive guards against invalid code points in preferences.
new 57335c4461 Merge pull request #6094 from mbien/invalid-code-point
a208c991c1 is described below
commit a208c991c13e9a77f429577d36016b5d770391ac
Author: Michael Bien <[email protected]>
AuthorDate: Mon Jun 19 09:02:16 2023 +0200
Defensive guards against invalid code points in preferences.
Made sure that OptionsExportModel is closing streams and zip files.
---
.../tools/ant/module/api/IntrospectedInfo.java | 15 +-
.../maven/queries/MavenFileOwnerQueryImpl.java | 15 +-
.../src/org/netbeans/upgrade/CopyFiles.java | 11 ++
.../netbeans/core/windows/TopComponentTracker.java | 8 +-
.../modules/options/export/OptionsExportModel.java | 175 +++++++++------------
5 files changed, 114 insertions(+), 110 deletions(-)
diff --git
a/extide/o.apache.tools.ant.module/src/org/apache/tools/ant/module/api/IntrospectedInfo.java
b/extide/o.apache.tools.ant.module/src/org/apache/tools/ant/module/api/IntrospectedInfo.java
index 728bc09cd6..eec4a7a3fc 100644
---
a/extide/o.apache.tools.ant.module/src/org/apache/tools/ant/module/api/IntrospectedInfo.java
+++
b/extide/o.apache.tools.ant.module/src/org/apache/tools/ant/module/api/IntrospectedInfo.java
@@ -674,22 +674,30 @@ public final class IntrospectedInfo {
null | String[] enumTags: .enumTags=whenempty,always,never
*/
Pattern p =
Pattern.compile("(.+)\\.(supportsText|attrs\\.(.+)|subs\\.(.+)|enumTags)");
+ @Override
public IntrospectedInfo load(Preferences node) {
IntrospectedInfo ii = new IntrospectedInfo();
try {
for (String k : node.keys()) {
- String v = node.get(k, null);
+ String v;
+ try {
+ v = node.get(k, null);
+ } catch (IllegalArgumentException ex) { // e.g invalid
code point JDK-8075156
+ LOG.log(Level.WARNING, "malformed key: {0}, pref
path: {1}, msg: {2}",
+ new Object[] {k, node.absolutePath(),
ex.getMessage()});
+ continue;
+ }
assert v != null : k;
String[] ss = k.split("\\.", 2);
if (ss.length != 2) {
- LOG.log(Level.WARNING, "malformed key: {0}", k);
+ LOG.log(Level.WARNING, "malformed key: {0}, pref
path: {1}", new Object[] {k, node.absolutePath()});
continue;
}
if (ss[0].equals("class")) {
Matcher m = p.matcher(ss[1]);
boolean match = m.matches();
if (!match) {
- LOG.log(Level.WARNING, "malformed key: {0}",
k);
+ LOG.log(Level.WARNING, "malformed key: {0},
pref path: {1}", new Object[] {k, node.absolutePath()});
continue;
}
String c = m.group(1);
@@ -742,6 +750,7 @@ public final class IntrospectedInfo {
}
return ic;
}
+ @Override
public void store(Preferences node, IntrospectedInfo info) {
try {
node.clear();
diff --git
a/java/maven/src/org/netbeans/modules/maven/queries/MavenFileOwnerQueryImpl.java
b/java/maven/src/org/netbeans/modules/maven/queries/MavenFileOwnerQueryImpl.java
index 996fd24526..98b87167f4 100644
---
a/java/maven/src/org/netbeans/modules/maven/queries/MavenFileOwnerQueryImpl.java
+++
b/java/maven/src/org/netbeans/modules/maven/queries/MavenFileOwnerQueryImpl.java
@@ -59,7 +59,6 @@ import org.netbeans.spi.project.FileOwnerQueryImplementation;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.filesystems.URLMapper;
-import org.openide.util.Exceptions;
import org.openide.util.Lookup;
import org.openide.util.NbPreferences;
import org.openide.util.Utilities;
@@ -75,9 +74,9 @@ public class MavenFileOwnerQueryImpl implements
FileOwnerQueryImplementation {
private final PropertyChangeListener projectListener;
private final ProjectGroupChangeListener groupListener;
- private final List<ChangeListener> listeners = new
CopyOnWriteArrayList<ChangeListener>();
+ private final List<ChangeListener> listeners = new
CopyOnWriteArrayList<>();
- private static final AtomicReference<Preferences> prefs = new
AtomicReference<Preferences>(NbPreferences.forModule(MavenFileOwnerQueryImpl.class).node(EXTERNAL_OWNERS));
+ private static final AtomicReference<Preferences> prefs = new
AtomicReference<>(NbPreferences.forModule(MavenFileOwnerQueryImpl.class).node(EXTERNAL_OWNERS));
private static final Logger LOG =
Logger.getLogger(MavenFileOwnerQueryImpl.class.getName());
@@ -150,7 +149,15 @@ public class MavenFileOwnerQueryImpl implements
FileOwnerQueryImplementation {
String ownerString = owner.toString();
try {
for (String k : prefs().keys()) {
- if (ownerString.equals(prefs().get(k, null))) {
+ String value;
+ try {
+ value = prefs().get(k, null);
+ } catch (IllegalArgumentException ex) {
+ // e.g invalid code point JDK-8075156
+ LOG.log(Level.WARNING, "Invalid prefrences key at {0},
msg: {1}", new Object[] { prefs().absolutePath(), ex.getMessage() });
+ continue;
+ }
+ if (ownerString.equals(value)) {
prefs().remove(k);
break;
}
diff --git a/nb/o.n.upgrader/src/org/netbeans/upgrade/CopyFiles.java
b/nb/o.n.upgrader/src/org/netbeans/upgrade/CopyFiles.java
index 804fb3e980..f52ed87364 100644
--- a/nb/o.n.upgrader/src/org/netbeans/upgrade/CopyFiles.java
+++ b/nb/o.n.upgrader/src/org/netbeans/upgrade/CopyFiles.java
@@ -27,6 +27,7 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
+import java.nio.file.Files;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry;
@@ -39,6 +40,8 @@ import org.netbeans.util.Util;
import org.openide.filesystems.FileUtil;
import org.openide.util.EditableProperties;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
/** Does copy of files according to include/exclude patterns.
*
* @author Jiri Skrivanek
@@ -136,6 +139,14 @@ final class CopyFiles extends Object {
* @throws java.io.IOException if copying fails
*/
private void copyFile(File sourceFile) throws IOException {
+
+ // invalid code point check JDK-8075156
+ if (sourceFile.getName().endsWith(".properties")
+ && new String(Files.readAllBytes(sourceFile.toPath()),
UTF_8).indexOf('\u0000') != -1) {
+ LOGGER.log(Level.WARNING, "{0} contains invalid code points ->
skipping", sourceFile); //NOI18N
+ return;
+ }
+
String relativePath = getRelativePath(sourceRoot, sourceFile);
currentProperties = null;
boolean includeFile = false;
diff --git
a/platform/core.windows/src/org/netbeans/core/windows/TopComponentTracker.java
b/platform/core.windows/src/org/netbeans/core/windows/TopComponentTracker.java
index 8f07395e32..61f50ddf60 100644
---
a/platform/core.windows/src/org/netbeans/core/windows/TopComponentTracker.java
+++
b/platform/core.windows/src/org/netbeans/core/windows/TopComponentTracker.java
@@ -73,7 +73,13 @@ public final class TopComponentTracker {
Preferences prefs = getPreferences();
try {
for( String key : prefs.keys() ) {
- boolean view = prefs.getBoolean( key, false );
+ boolean view;
+ try {
+ view = prefs.getBoolean( key, false );
+ } catch (IllegalArgumentException ex) {
+
Logger.getLogger(TopComponentTracker.class.getName()).log(Level.INFO, "invalid
preferences key", ex);
+ continue; // e.g invalid code point JDK-8075156
+ }
if( view )
viewIds.add( key );
else
diff --git
a/platform/options.api/src/org/netbeans/modules/options/export/OptionsExportModel.java
b/platform/options.api/src/org/netbeans/modules/options/export/OptionsExportModel.java
index 40c4f5daa4..7a48551aa5 100644
---
a/platform/options.api/src/org/netbeans/modules/options/export/OptionsExportModel.java
+++
b/platform/options.api/src/org/netbeans/modules/options/export/OptionsExportModel.java
@@ -18,6 +18,7 @@
*/
package org.netbeans.modules.options.export;
+import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
@@ -110,19 +111,19 @@ public final class OptionsExportModel {
ArrayList<String> getEnabledItemsDuringExport(File importSource) {
ArrayList<String> enabledItems = null;
if (importSource.isFile()) { // importing from .zip file
- try {
- ZipFile zipFile = new ZipFile(importSource);
+ try (ZipFile zipFile = new ZipFile(importSource)) {
// Enumerate each entry
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
- ZipEntry zipEntry = (ZipEntry) entries.nextElement();
+ ZipEntry zipEntry = entries.nextElement();
if(zipEntry.getName().equals(OptionsExportModel.ENABLED_ITEMS_INFO)) {
- enabledItems = new ArrayList<String>();
- InputStream stream = zipFile.getInputStream(zipEntry);
- BufferedReader br = new BufferedReader(new
InputStreamReader(stream, StandardCharsets.UTF_8));
- String strLine;
- while ((strLine = br.readLine()) != null) {
- enabledItems.add(strLine);
+ enabledItems = new ArrayList<>();
+ try (InputStream stream =
zipFile.getInputStream(zipEntry);
+ BufferedReader br = new BufferedReader(new
InputStreamReader(stream, StandardCharsets.UTF_8));) {
+ String strLine;
+ while ((strLine = br.readLine()) != null) {
+ enabledItems.add(strLine);
+ }
}
}
}
@@ -158,20 +159,20 @@ public final class OptionsExportModel {
double getBuildNumberDuringExport(File importSource) {
String buildNumber = null;
if (importSource.isFile()) { // importing from .zip file
- try {
- ZipFile zipFile = new ZipFile(importSource);
+ try (ZipFile zipFile = new ZipFile(importSource)) {
// Enumerate each entry
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry zipEntry = (ZipEntry) entries.nextElement();
if
(zipEntry.getName().equals(OptionsExportModel.BUILD_INFO)) {
- InputStream stream = zipFile.getInputStream(zipEntry);
- BufferedReader br = new BufferedReader(new
InputStreamReader(stream, StandardCharsets.UTF_8));
- String strLine;
- while ((strLine = br.readLine()) != null) {
- buildNumber = parseBuildNumber(strLine);
- if(buildNumber != null) {
- break; // successfully parsed build number, no
need to continue
+ try (InputStream stream =
zipFile.getInputStream(zipEntry);
+ BufferedReader br = new BufferedReader(new
InputStreamReader(stream, StandardCharsets.UTF_8));) {
+ String strLine;
+ while ((strLine = br.readLine()) != null) {
+ buildNumber = parseBuildNumber(strLine);
+ if(buildNumber != null) {
+ break; // successfully parsed build
number, no need to continue
+ }
}
}
}
@@ -304,24 +305,16 @@ public final class OptionsExportModel {
try {
ensureParent(targetZipFile);
// Create the ZIP file
- zipOutputStream = new
ZipOutputStream(createOutputStream(targetZipFile));
- copyFiles();
- createEnabledItemsInfo(zipOutputStream, enabledItems);
- createProductInfo(zipOutputStream);
- // Complete the ZIP file
- zipOutputStream.close();
+ try (ZipOutputStream out = new
ZipOutputStream(createOutputStream(targetZipFile))) {
+ zipOutputStream = out;
+ copyFiles();
+ createEnabledItemsInfo(out, enabledItems);
+ createProductInfo(out);
+ }
} catch (IOException ex) {
Exceptions.attachLocalizedMessage(ex,
NbBundle.getMessage(OptionsExportModel.class,
"OptionsExportModel.export.zip.error", targetZipFile));
Exceptions.printStackTrace(ex);
- } finally {
- if (zipOutputStream != null) {
- try {
- zipOutputStream.close();
- } catch (IOException ex) {
- // ignore
- }
- }
}
}
@@ -748,21 +741,31 @@ public final class OptionsExportModel {
*/
private void copyZipFile() throws IOException {
// Open the ZIP file
- ZipFile zipFile = new ZipFile(source);
- try {
+ try (ZipFile zipFile = new ZipFile(source)) {
// Enumerate each entry
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry zipEntry = entries.nextElement();
- if (!zipEntry.isDirectory()) {
+ if (!zipEntry.isDirectory() && !checkIntegrity(zipEntry)) {
copyFile(zipEntry.getName());
}
}
- } finally {
- if (zipFile != null) {
- zipFile.close();
+ }
+ }
+
+ private boolean checkIntegrity(ZipEntry entry) throws IOException {
+ if (entry.getName().endsWith(".properties")) {
+ try (ZipFile zip = new ZipFile(source);
+ BufferedReader reader = new BufferedReader(new
InputStreamReader(zip.getInputStream(entry), StandardCharsets.UTF_8))) {
+ // invalid code point check JDK-8075156
+ boolean corrupted = reader.lines().anyMatch(l ->
l.indexOf('\u0000') != -1);
+ if (corrupted) {
+ LOGGER.log(Level.WARNING, "ignoring corrupted properties
file at {0}", entry.getName());
+ }
+ return corrupted;
}
}
+ return true;
}
/** Copy given folder to target userdir or zip file obeying
include/exclude patterns.
@@ -964,18 +967,12 @@ public final class OptionsExportModel {
// Complete the entry
zipOutputStream.closeEntry();
} else { // import to userdir
- OutputStream out = null;
File targetFile = new File(targetUserdir, relativePath);
LOGGER.log(Level.FINE, "Path: {0}", relativePath); //NOI18N
if (includeKeys.isEmpty() && excludeKeys.isEmpty()) {
// copy entire file
- try {
- out = createOutputStream(targetFile);
+ try (OutputStream out = createOutputStream(targetFile)) {
copyFile(relativePath, out);
- } finally {
- if (out != null) {
- out.close();
- }
}
} else {
mergeProperties(relativePath, includeKeys, excludeKeys);
@@ -999,29 +996,17 @@ public final class OptionsExportModel {
return;
}
EditableProperties targetProperties = new EditableProperties(false);
- InputStream in = null;
File targetFile = new File(targetUserdir, relativePath);
- try {
- if (targetFile.exists()) {
- in = new FileInputStream(targetFile);
+ if (targetFile.exists()) {
+ try (InputStream in = new FileInputStream(targetFile)) {
targetProperties.load(in);
}
- } finally {
- if (in != null) {
- in.close();
- }
}
for (Entry<String, String> entry : currentProperties.entrySet()) {
targetProperties.put(entry.getKey(), entry.getValue());
}
- OutputStream out = null;
- try {
- out = createOutputStream(targetFile);
+ try (OutputStream out = createOutputStream(targetFile)) {
targetProperties.store(out);
- } finally {
- if (out != null) {
- out.close();
- }
}
}
@@ -1055,14 +1040,8 @@ public final class OptionsExportModel {
*/
private EditableProperties getProperties(String relativePath) throws
IOException {
EditableProperties properties = new EditableProperties(false);
- InputStream in = null;
- try {
- in = getInputStream(relativePath);
+ try (InputStream in = getInputStream(relativePath)) {
properties.load(in);
- } finally {
- if (in != null) {
- in.close();
- }
}
return properties;
}
@@ -1075,29 +1054,35 @@ public final class OptionsExportModel {
private InputStream getInputStream(String relativePath) throws IOException
{
if (source.isFile()) {
//zip file
- ZipFile zipFile = new ZipFile(source);
- ZipEntry zipEntry = zipFile.getEntry(relativePath);
- return zipFile.getInputStream(zipEntry);
+ return singleEntryZipStream(relativePath);
} else {
// userdir
return new FileInputStream(new File(source, relativePath));
}
}
+ private InputStream singleEntryZipStream(String relativePath) throws
IOException {
+ final ZipFile zipFile = new ZipFile(source);
+ return new
BufferedInputStream(zipFile.getInputStream(zipFile.getEntry(relativePath))) {
+ @Override
+ public void close() throws IOException {
+ try {
+ super.close();
+ } finally {
+ zipFile.close();
+ }
+ }
+ };
+ }
+
/** Copy file from relative path in zip file or userdir to target
OutputStream.
* @param relativePath relative path
* @param out output stream
* @throws java.io.IOException if copying fails
*/
private void copyFile(String relativePath, OutputStream out) throws
IOException {
- InputStream in = null;
- try {
- in = getInputStream(relativePath);
+ try (InputStream in = getInputStream(relativePath)) {
FileUtil.copy(in, out);
- } finally {
- if (in != null) {
- in.close();
- }
}
}
@@ -1117,15 +1102,16 @@ public final class OptionsExportModel {
* @throws java.io.IOException
*/
static List<String> listZipFile(File file) throws IOException {
- List<String> relativePaths = new ArrayList<String>();
+ List<String> relativePaths = new ArrayList<>();
// Open the ZIP file
- ZipFile zipFile = new ZipFile(file);
- // Enumerate each entry
- Enumeration<? extends ZipEntry> entries = zipFile.entries();
- while (entries.hasMoreElements()) {
- ZipEntry zipEntry = (ZipEntry) entries.nextElement();
- if (!zipEntry.isDirectory()) {
- relativePaths.add(zipEntry.getName());
+ try (ZipFile zipFile = new ZipFile(file)) {
+ // Enumerate each entry
+ Enumeration<? extends ZipEntry> entries = zipFile.entries();
+ while (entries.hasMoreElements()) {
+ ZipEntry zipEntry = entries.nextElement();
+ if (!zipEntry.isDirectory()) {
+ relativePaths.add(zipEntry.getName());
+ }
}
}
return relativePaths;
@@ -1139,35 +1125,20 @@ public final class OptionsExportModel {
*/
static void createZipFile(File targetFile, File sourceDir, List<String>
relativePaths) throws IOException {
ensureParent(targetFile);
- ZipOutputStream out = null;
- try {
- // Create the ZIP file
- out = new ZipOutputStream(createOutputStream(targetFile));
+ try (ZipOutputStream out = new
ZipOutputStream(createOutputStream(targetFile))) {
// Compress the files
for (String relativePath : relativePaths) {
LOGGER.finest("Adding to zip: " + relativePath); //NOI18N
// Add ZIP entry to output stream.
out.putNextEntry(new ZipEntry(relativePath));
// Transfer bytes from the file to the ZIP file
- FileInputStream in = null;
- try {
- in = new FileInputStream(new File(sourceDir,
relativePath));
+ try (FileInputStream in = new FileInputStream(new
File(sourceDir, relativePath))) {
FileUtil.copy(in, out);
- } finally {
- if (in != null) {
- in.close();
- }
}
// Complete the entry
out.closeEntry();
}
createProductInfo(out);
- // Complete the ZIP file
- out.close();
- } finally {
- if (out != null) {
- out.close();
- }
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists