Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2017-07-27 17:30:07 +0000
committerThomas Watson2017-08-11 13:23:07 +0000
commit2c8c788dacedb082584bd9854bed71dd7d6bcac0 (patch)
tree6dbc16351f31a6940763541d3f65096f119e144a
parent6a31629a6dfa73f19b646f7f98e65749aabd8810 (diff)
downloadrt.equinox.framework-2c8c788dacedb082584bd9854bed71dd7d6bcac0.tar.gz
rt.equinox.framework-2c8c788dacedb082584bd9854bed71dd7d6bcac0.tar.xz
rt.equinox.framework-2c8c788dacedb082584bd9854bed71dd7d6bcac0.zip
Bug 520281 - NPE possible if null values are used to match against a
filter Change-Id: Id7faf62585006ff6b3350e07de214d611267db75 Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
-rw-r--r--bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.osgi.tests/pom.xml2
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/filter/FilterTests.java18
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/serviceregistry/ServiceRegistryTests.java33
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/util/MapDictionary.java53
-rw-r--r--bundles/org.eclipse.osgi/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/framework/util/CaseInsensitiveDictionaryMap.java49
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceProperties.java6
-rw-r--r--bundles/org.eclipse.osgi/pom.xml2
9 files changed, 135 insertions, 32 deletions
diff --git a/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF
index 9fc3c16dd..659cdd24f 100644
--- a/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Core OSGi Tests
Bundle-SymbolicName: org.eclipse.osgi.tests;singleton:=true
-Bundle-Version: 3.12.0.qualifier
+Bundle-Version: 3.12.1.qualifier
Bundle-Vendor: Eclipse.org
Bundle-Localization: plugin
Require-Bundle:
diff --git a/bundles/org.eclipse.osgi.tests/pom.xml b/bundles/org.eclipse.osgi.tests/pom.xml
index f9d6d9387..5d57bec5a 100644
--- a/bundles/org.eclipse.osgi.tests/pom.xml
+++ b/bundles/org.eclipse.osgi.tests/pom.xml
@@ -19,7 +19,7 @@
</parent>
<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi.tests</artifactId>
- <version>3.12.0-SNAPSHOT</version>
+ <version>3.12.1-SNAPSHOT</version>
<packaging>eclipse-test-plugin</packaging>
<properties>
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/filter/FilterTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/filter/FilterTests.java
index 95d4d5687..62dc32e7c 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/filter/FilterTests.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/filter/FilterTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2015 IBM Corporation and others.
+ * Copyright (c) 2008, 2017 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -14,6 +14,7 @@ import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import junit.framework.*;
+import org.eclipse.osgi.tests.util.MapDictionary;
import org.osgi.framework.*;
public abstract class FilterTests extends TestCase {
@@ -343,6 +344,21 @@ public abstract class FilterTests extends TestCase {
assertFalse("does match filter", f1.match(new DictionaryServiceReference(hash)));
}
+ public void testNullValueMatch() throws InvalidSyntaxException {
+ Dictionary<String, Object> nullProps = new MapDictionary<String, Object>();
+ nullProps.put("test.null", null);
+ nullProps.put("test.non.null", "v1");
+ assertFalse(createFilter("(test.null=*)").match(nullProps));
+ assertTrue(createFilter("(&(!(test.null=*))(test.non.null=v1))").match(nullProps));
+ }
+
+ public void testNullKeyMatch() throws InvalidSyntaxException {
+ Dictionary<String, Object> nullProps = new MapDictionary<String, Object>();
+ nullProps.put(null, "null.v1");
+ nullProps.put("test.non.null", "v1");
+ assertTrue(createFilter("(test.non.null=v1)").match(nullProps));
+ }
+
public static class SampleComparable implements Comparable {
private int value = -1;
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/serviceregistry/ServiceRegistryTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/serviceregistry/ServiceRegistryTests.java
index 5de8e206b..81e2af168 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/serviceregistry/ServiceRegistryTests.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/serviceregistry/ServiceRegistryTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2014 IBM Corporation and others.
+ * Copyright (c) 2008, 2017 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.osgi.tests.serviceregistry;
+import java.util.Dictionary;
import java.util.Hashtable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -17,6 +18,7 @@ import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.osgi.tests.OSGiTestsActivator;
import org.eclipse.osgi.tests.bundles.AbstractBundleTests;
+import org.eclipse.osgi.tests.util.MapDictionary;
import org.osgi.framework.*;
public class ServiceRegistryTests extends AbstractBundleTests {
@@ -523,6 +525,35 @@ public class ServiceRegistryTests extends AbstractBundleTests {
}
+ public void testNullValue() throws InvalidSyntaxException {
+ ServiceRegistration reg = null;
+ try {
+ Dictionary<String, Object> nullProps = new MapDictionary<String, Object>();
+ nullProps.put("test.null", null);
+ nullProps.put("test.non.null", "v1");
+ reg = OSGiTestsActivator.getContext().registerService(Object.class, new Object(), nullProps);
+ assertFalse(OSGiTestsActivator.getContext().createFilter("(test.null=*)").match(reg.getReference()));
+ assertTrue(OSGiTestsActivator.getContext().createFilter("(&(!(test.null=*))(test.non.null=v1))").match(reg.getReference()));
+ } finally {
+ if (reg != null)
+ reg.unregister();
+ }
+ }
+
+ public void testNullKey() throws InvalidSyntaxException {
+ ServiceRegistration reg = null;
+ try {
+ Dictionary<String, Object> nullProps = new MapDictionary<String, Object>();
+ nullProps.put(null, "null.v1");
+ nullProps.put("test.non.null", "v1");
+ reg = OSGiTestsActivator.getContext().registerService(Object.class, new Object(), nullProps);
+ assertTrue(OSGiTestsActivator.getContext().createFilter("(test.non.null=v1)").match(reg.getReference()));
+ } finally {
+ if (reg != null)
+ reg.unregister();
+ }
+ }
+
private void clearResults(boolean[] results) {
for (int i = 0; i < results.length; i++)
results[i] = false;
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/util/MapDictionary.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/util/MapDictionary.java
new file mode 100644
index 000000000..d3afdb187
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/util/MapDictionary.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2017 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.osgi.tests.util;
+
+import java.util.*;
+
+public class MapDictionary<K, V> extends Dictionary<K, V> {
+ Map<K, V> map = new HashMap<K, V>();
+
+ @Override
+ public int size() {
+ return map.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return map.isEmpty();
+ }
+
+ @Override
+ public Enumeration<K> keys() {
+ return Collections.enumeration(map.keySet());
+ }
+
+ @Override
+ public Enumeration<V> elements() {
+ return Collections.enumeration(map.values());
+ }
+
+ @Override
+ public V get(Object key) {
+ return map.get(key);
+ }
+
+ @Override
+ public V put(K key, V value) {
+ return map.put(key, value);
+ }
+
+ @Override
+ public V remove(Object key) {
+ return map.remove(key);
+ }
+
+}
diff --git a/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF
index 0f7985ae0..0978188c2 100644
--- a/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF
@@ -103,7 +103,7 @@ Bundle-Activator: org.eclipse.osgi.internal.framework.SystemBundleActivator
Bundle-Description: %systemBundle
Bundle-Copyright: %copyright
Bundle-Vendor: %eclipse.org
-Bundle-Version: 3.12.0.qualifier
+Bundle-Version: 3.12.1.qualifier
Bundle-Localization: systembundle
Bundle-DocUrl: http://www.eclipse.org
Eclipse-ExtensibleAPI: true
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/framework/util/CaseInsensitiveDictionaryMap.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/framework/util/CaseInsensitiveDictionaryMap.java
index 545cc9008..a4700be3e 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/framework/util/CaseInsensitiveDictionaryMap.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/framework/util/CaseInsensitiveDictionaryMap.java
@@ -59,8 +59,15 @@ public class CaseInsensitiveDictionaryMap<K, V> extends Dictionary<K, V> impleme
Enumeration<? extends K> keys = dictionary.keys();
while (keys.hasMoreElements()) {
K key = keys.nextElement();
- if (put(key, dictionary.get(key)) != null) {
- throw new IllegalArgumentException(NLS.bind(Msg.HEADER_DUPLICATE_KEY_EXCEPTION, key));
+ // ignore null keys
+ if (key != null) {
+ V value = dictionary.get(key);
+ // ignore null values
+ if (value != null) {
+ if (put(key, value) != null) {
+ throw new IllegalArgumentException(NLS.bind(Msg.HEADER_DUPLICATE_KEY_EXCEPTION, key));
+ }
+ }
}
}
}
@@ -76,8 +83,16 @@ public class CaseInsensitiveDictionaryMap<K, V> extends Dictionary<K, V> impleme
this(initialCapacity(map.size()));
/* initialize the keys and values */
for (Entry<? extends K, ? extends V> e : map.entrySet()) {
- if (put(e.getKey(), e.getValue()) != null) {
- throw new IllegalArgumentException(NLS.bind(Msg.HEADER_DUPLICATE_KEY_EXCEPTION, e.getKey()));
+ K key = e.getKey();
+ // ignore null keys
+ if (key != null) {
+ V value = e.getValue();
+ // ignore null values
+ if (value != null) {
+ if (put(key, value) != null) {
+ throw new IllegalArgumentException(NLS.bind(Msg.HEADER_DUPLICATE_KEY_EXCEPTION, key));
+ }
+ }
}
}
}
@@ -112,13 +127,11 @@ public class CaseInsensitiveDictionaryMap<K, V> extends Dictionary<K, V> impleme
/**
* {@inheritDoc}
* <p>
- * The key must be non-null.
- * <p>
* If the key is a String, the key is located in a case-insensitive manner.
*/
@Override
public V get(Object key) {
- return map.get(keyWrap(requireNonNull(key)));
+ return map.get(keyWrap(key));
}
/**
@@ -173,13 +186,11 @@ public class CaseInsensitiveDictionaryMap<K, V> extends Dictionary<K, V> impleme
/**
* {@inheritDoc}
* <p>
- * The key must be non-null.
- * <p>
* If the key is a String, the key is removed in a case-insensitive manner.
*/
@Override
public V remove(Object key) {
- return map.remove(keyWrap(requireNonNull(key)));
+ return map.remove(keyWrap(key));
}
/**
@@ -201,23 +212,19 @@ public class CaseInsensitiveDictionaryMap<K, V> extends Dictionary<K, V> impleme
/**
* {@inheritDoc}
* <p>
- * The key must be non-null.
- * <p>
* If the key is a String, the key is located in a case-insensitive manner.
*/
@Override
public boolean containsKey(Object key) {
- return map.containsKey(keyWrap(requireNonNull(key)));
+ return map.containsKey(keyWrap(key));
}
/**
* {@inheritDoc}
- * <p>
- * The value must be non-null.
*/
@Override
public boolean containsValue(Object value) {
- return map.containsValue(requireNonNull(value));
+ return map.containsValue(value);
}
private transient Set<Entry<K, V>> entrySet = null;
@@ -556,7 +563,7 @@ public class CaseInsensitiveDictionaryMap<K, V> extends Dictionary<K, V> impleme
@Override
public int hashCode() {
- return entry.getKey().hashCode() ^ entry.getValue().hashCode();
+ return Objects.hashCode(entry.getKey()) ^ Objects.hashCode(entry.getValue());
}
@Override
@@ -566,13 +573,7 @@ public class CaseInsensitiveDictionaryMap<K, V> extends Dictionary<K, V> impleme
Object k1 = entry.getKey();
@SuppressWarnings("unchecked")
Object k2 = (other instanceof CaseInsentiveEntry) ? ((CaseInsentiveEntry<K, V>) other).entry.getKey() : other.getKey();
- if ((k1 == k2) || k1.equals(k2)) {
- Object v1 = entry.getValue();
- Object v2 = other.getValue();
- if ((v1 == v2) || v1.equals(v2)) {
- return true;
- }
- }
+ return Objects.equals(k1, k2) && Objects.equals(entry.getValue(), other.getValue());
}
return false;
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceProperties.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceProperties.java
index b875b6cf3..b6646d431 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceProperties.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceProperties.java
@@ -54,7 +54,8 @@ class ServiceProperties extends CaseInsensitiveDictionaryMap<String, Object> {
Object key = keysEnum.nextElement();
if (key instanceof String) {
String header = (String) key;
- if (put(header, cloneValue(props.get(header))) != null) {
+ Object value = cloneValue(props.get(header));
+ if (value != null && put(header, value) != null) {
throw new IllegalArgumentException(NLS.bind(Msg.HEADER_DUPLICATE_KEY_EXCEPTION, key));
}
}
@@ -79,7 +80,8 @@ class ServiceProperties extends CaseInsensitiveDictionaryMap<String, Object> {
Object key = e.getKey();
if (key instanceof String) {
String header = (String) key;
- if (put(header, cloneValue(e.getValue())) != null) {
+ Object value = cloneValue(props.get(header));
+ if (value != null && put(header, value) != null) {
throw new IllegalArgumentException(NLS.bind(Msg.HEADER_DUPLICATE_KEY_EXCEPTION, key));
}
}
diff --git a/bundles/org.eclipse.osgi/pom.xml b/bundles/org.eclipse.osgi/pom.xml
index 9e6a5f6c6..228ba6028 100644
--- a/bundles/org.eclipse.osgi/pom.xml
+++ b/bundles/org.eclipse.osgi/pom.xml
@@ -19,7 +19,7 @@
</parent>
<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi</artifactId>
- <version>3.12.0-SNAPSHOT</version>
+ <version>3.12.1-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<build>

Back to the top