Merge content from HEAD (tag v20100730)
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/protocol/MultiplexingFactory.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/protocol/MultiplexingFactory.java
index f0f2c46..1d06aba 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/protocol/MultiplexingFactory.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/protocol/MultiplexingFactory.java
@@ -12,7 +12,6 @@
import java.util.*;
import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor;
import org.eclipse.osgi.framework.internal.core.AbstractBundle;
-import org.eclipse.osgi.framework.internal.core.Framework;
import org.eclipse.osgi.framework.log.FrameworkLogEntry;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
@@ -54,32 +53,24 @@
abstract public Object getParentFactory();
- public synchronized boolean isMultiplexing() {
- return factories != null || composites != null;
+ public boolean isMultiplexing() {
+ return getFactories() != null || getComposites() != null;
}
- public synchronized void registerComposite(MultiplexingFactory compositeFactory) {
- if (composites == null)
- composites = new LinkedList<MultiplexingFactory>();
- compositeFactory.setParentFactory(getParentFactory());
- composites.add(compositeFactory);
+ public void registerComposite(MultiplexingFactory compositeFactory) {
+ addComposite(compositeFactory);
// always reset the handers so we can force in multiplexing ones
resetHandlers();
}
protected abstract void resetHandlers();
- public synchronized void unregisterComposite(MultiplexingFactory compositeFactory) {
- composites.remove(compositeFactory);
- if (composites.isEmpty())
- composites = null;
+ public void unregisterComposite(MultiplexingFactory compositeFactory) {
+ removeComposite(compositeFactory);
compositeFactory.closePackageAdminTracker();
}
- public synchronized void register(Object factory) {
- if (factories == null)
- factories = new LinkedList();
-
+ public void register(Object factory) {
// set parent for each factory so they can do proper delegation
try {
Class clazz = factory.getClass();
@@ -89,19 +80,13 @@
adaptor.getFrameworkLog().log(new FrameworkLogEntry(MultiplexingFactory.class.getName(), FrameworkLogEntry.ERROR, 0, "register", FrameworkLogEntry.ERROR, e, null)); //$NON-NLS-1$
throw new RuntimeException(e.getMessage(), e);
}
- factories.add(factory);
+ addFactory(factory);
// always reset the handers so we can force in multiplexing ones
- try {
- Framework.resetURLStreamHandlers();
- } catch (IllegalAccessException e) {
- // TODO log
- }
+ resetHandlers();
}
- public synchronized void unregister(Object factory) {
- factories.remove(factory);
- if (factories.isEmpty())
- factories = null;
+ public void unregister(Object factory) {
+ removeFactory(factory);
// close the service tracker
try {
// this is brittle; if class does not directly extend MultplexingFactory then this method will not exist, but we do not want a public method here
@@ -114,23 +99,29 @@
}
}
- public synchronized Object designateSuccessor() {
- Object parentFactory = getParentFactory();
- if (factories == null || factories.isEmpty())
- return parentFactory;
-
- Object successor = factories.remove(0);
+ public Object designateSuccessor() {
+ List released = releaseFactories();
+ // Note that we do this outside of the sync block above.
+ // This is only possible because we do additional locking outside of
+ // this class to ensure no other threads are trying to manipulate the
+ // list of registered factories. See Framework class the following methods:
+ // Framework.installURLStreamHandlerFactory(BundleContext, FrameworkAdaptor)
+ // Framework.installContentHandlerFactory(BundleContext, FrameworkAdaptor)
+ // Framework.uninstallURLStreamHandlerFactory
+ // Framework.uninstallContentHandlerFactory()
+ if (released == null || released.isEmpty())
+ return getParentFactory();
+ Object successor = released.remove(0);
try {
Class clazz = successor.getClass();
Method register = clazz.getMethod("register", new Class[] {Object.class}); //$NON-NLS-1$
- for (Iterator it = factories.iterator(); it.hasNext();) {
+ for (Iterator it = released.iterator(); it.hasNext();) {
register.invoke(successor, new Object[] {it.next()});
}
} catch (Exception e) {
adaptor.getFrameworkLog().log(new FrameworkLogEntry(MultiplexingFactory.class.getName(), FrameworkLogEntry.ERROR, 0, "designateSuccessor", FrameworkLogEntry.ERROR, e, null)); //$NON-NLS-1$
throw new RuntimeException(e.getMessage(), e);
}
- factories = null;
closePackageAdminTracker(); // close tracker
return successor;
}
@@ -139,7 +130,9 @@
packageAdminTracker.close();
}
- public synchronized Object findAuthorizedFactory(List ignoredClasses) {
+ public Object findAuthorizedFactory(List ignoredClasses) {
+ List currentFactories = getFactories();
+ List<MultiplexingFactory> currentComposites = getComposites();
Class[] classStack = internalSecurityManager.getClassContext();
for (int i = 0; i < classStack.length; i++) {
Class clazz = classStack[i];
@@ -147,14 +140,14 @@
continue;
if (hasAuthority(clazz))
return this;
- if (composites != null)
- for (Iterator<MultiplexingFactory> iComposites = composites.iterator(); iComposites.hasNext();) {
+ if (currentComposites != null)
+ for (Iterator<MultiplexingFactory> iComposites = currentComposites.iterator(); iComposites.hasNext();) {
MultiplexingFactory composite = iComposites.next();
if (composite.hasAuthority(clazz))
return composite;
}
- if (factories != null)
- for (Iterator it = factories.iterator(); it.hasNext();) {
+ if (currentFactories != null)
+ for (Iterator it = currentFactories.iterator(); it.hasNext();) {
Object factory = it.next();
try {
Method hasAuthorityMethod = factory.getClass().getMethod("hasAuthority", new Class[] {Class.class}); //$NON-NLS-1$
@@ -193,8 +186,49 @@
* Returns the composite id for this factory. If this is not part of any composites -1 is returned.
* @return the composite id for this factory
*/
- protected synchronized long getCompositeId() {
- return (composites == null && compositeId == 0) ? -1 : compositeId;
+ protected long getCompositeId() {
+ return (getComposites() == null && compositeId == 0) ? -1 : compositeId;
}
+
+ private synchronized List getFactories() {
+ return factories;
+ }
+
+ private synchronized List releaseFactories() {
+ if (factories == null)
+ return null;
+
+ List released = new LinkedList(factories);
+ factories = null;
+ return released;
+ }
+
+ private synchronized void addFactory(Object factory) {
+ List updated = (factories == null) ? new LinkedList() : new LinkedList(factories);
+ updated.add(factory);
+ factories = updated;
+ }
+
+ private synchronized void removeFactory(Object factory) {
+ List updated = new LinkedList(factories);
+ updated.remove(factory);
+ factories = updated.isEmpty() ? null : updated;
+ }
+
+ private synchronized List<MultiplexingFactory> getComposites() {
+ return composites;
+ }
+
+ private synchronized void addComposite(MultiplexingFactory composite) {
+ List<MultiplexingFactory> updated = (composites == null) ? new LinkedList<MultiplexingFactory>() : new LinkedList<MultiplexingFactory>(composites);
+ updated.add(composite);
+ composites = updated;
+ }
+
+ private synchronized void removeComposite(MultiplexingFactory composite) {
+ List<MultiplexingFactory> updated = new LinkedList<MultiplexingFactory>(composites);
+ updated.remove(composite);
+ composites = updated.isEmpty() ? null : updated;
+ }
}
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/protocol/StreamHandlerFactory.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/protocol/StreamHandlerFactory.java
index d80739a..512e52c 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/protocol/StreamHandlerFactory.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/protocol/StreamHandlerFactory.java
@@ -217,7 +217,7 @@
@Override
protected void resetHandlers() {
try {
- ((BundleContextImpl) context).getFramework().resetURLStreamHandlers();
+ Framework.resetURLStreamHandlers();
} catch (IllegalAccessException e) {
// TODO log
}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/DirBundleFile.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/DirBundleFile.java
index 3f8ee1d..1bf8643 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/DirBundleFile.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/DirBundleFile.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2010 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
@@ -37,33 +37,40 @@
}
public File getFile(String path, boolean nativeCode) {
- File filePath = new File(this.basefile, path);
- if (BundleFile.secureAction.exists(filePath)) {
- return filePath;
+ boolean checkInBundle = path != null && path.indexOf("..") >= 0; //$NON-NLS-1$
+ File file = new File(basefile, path);
+ if (!BundleFile.secureAction.exists(file)) {
+ return null;
}
- return null;
+ // must do an extra check to make sure file is within the bundle (bug 320546)
+ if (checkInBundle) {
+ try {
+ if (!BundleFile.secureAction.getCanonicalPath(file).startsWith(BundleFile.secureAction.getCanonicalPath(basefile)))
+ return null;
+ } catch (IOException e) {
+ return null;
+ }
+ }
+ return file;
}
public BundleEntry getEntry(String path) {
- File filePath = new File(this.basefile, path);
- if (!BundleFile.secureAction.exists(filePath)) {
+ File filePath = getFile(path, false);
+ if (filePath == null)
return null;
- }
return new FileBundleEntry(filePath, path);
}
public boolean containsDir(String dir) {
- File dirPath = new File(this.basefile, dir);
- return BundleFile.secureAction.exists(dirPath) && BundleFile.secureAction.isDirectory(dirPath);
+ File dirPath = getFile(dir, false);
+ return dirPath != null && BundleFile.secureAction.isDirectory(dirPath);
}
public Enumeration getEntryPaths(String path) {
if (path.length() > 0 && path.charAt(0) == '/')
path = path.substring(1);
- final java.io.File pathFile = new java.io.File(basefile, path);
- if (!BundleFile.secureAction.exists(pathFile))
- return null;
- if (!BundleFile.secureAction.isDirectory(pathFile))
+ final File pathFile = getFile(path, false);
+ if (pathFile == null || !BundleFile.secureAction.isDirectory(pathFile))
return null;
final String[] fileList = BundleFile.secureAction.list(pathFile);
if (fileList == null || fileList.length == 0)
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GroupingChecker.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GroupingChecker.java
index 79f9e59..9590d24 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GroupingChecker.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GroupingChecker.java
@@ -15,10 +15,10 @@
* The GroupingChecker checks the 'uses' directive on exported packages for consistency
*/
public class GroupingChecker {
- final PackageRoots nullPackageRoots = new PackageRoots(null, null);
+ final PackageRoots nullPackageRoots = new PackageRoots(null);
// a mapping of bundles to their package roots; keyed by
// ResolverBundle -> HashMap of packages; keyed by
- // package name -> PackageRoots[]
+ // package name -> PackageRoots
private HashMap bundles = new HashMap();
/*
@@ -110,7 +110,7 @@
for (Iterator allImportingPackages = importingPackages.values().iterator(); allImportingPackages.hasNext();) {
PackageRoots roots = (PackageRoots) allImportingPackages.next();
if (roots != importingRoots)
- results = roots.isConsistentClassSpace(exportingRoots, null, results);
+ results = roots.isConsistentClassSpace(exportingRoots, matchingExport.getExporter(), null, results);
}
return results;
}
@@ -193,7 +193,7 @@
return superSet;
}
// in this case we cannot share the package roots object; must create one specific for this bundle
- PackageRoots result = new PackageRoots(packageName, bundle);
+ PackageRoots result = new PackageRoots(packageName);
// first merge all the roots from required bundles
for (int i = 0; i < requiredRoots.length; i++)
result.merge(requiredRoots[i]);
@@ -215,12 +215,10 @@
class PackageRoots {
private String name;
- private ResolverBundle bundle;
private ResolverExport[] roots;
- PackageRoots(String name, ResolverBundle bundle) {
+ PackageRoots(String name) {
this.name = name;
- this.bundle = bundle;
}
public boolean hasRoots() {
@@ -298,7 +296,7 @@
return results;
}
- public ArrayList isConsistentClassSpace(PackageRoots exportingRoots, ArrayList visited, ArrayList results) {
+ public ArrayList isConsistentClassSpace(PackageRoots exportingRoots, ResolverBundle exporter, ArrayList visited, ArrayList results) {
if (roots == null)
return results;
int size = roots.length;
@@ -316,7 +314,7 @@
if (uses[j].equals(root.getName()) || !uses[j].equals(exportingRoots.name))
continue;
PackageRoots thisUsedRoots = getPackageRoots(root.getExporter(), uses[j], null);
- PackageRoots exportingUsedRoots = getPackageRoots(exportingRoots.bundle, uses[j], null);
+ PackageRoots exportingUsedRoots = getPackageRoots(exporter, uses[j], null);
if (thisUsedRoots == exportingRoots)
return results;
if (thisUsedRoots != nullPackageRoots && exportingUsedRoots != nullPackageRoots)
@@ -326,7 +324,7 @@
results.add(new PackageRoots[] {this, exportingUsedRoots});
}
// need to check the usedRoots consistency for transitive closure
- results = thisUsedRoots.isConsistentClassSpace(exportingRoots, visited, results);
+ results = thisUsedRoots.isConsistentClassSpace(exportingRoots, exporter, visited, results);
}
}
return results;
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateHelperImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateHelperImpl.java
index 9a295c6..e4ee07b 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateHelperImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateHelperImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * Copyright (c) 2004, 2010 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
@@ -559,9 +559,9 @@
for (int i = 0; i < fragments.length; i++) {
BundleSpecification[] fragmentRequiredBundles = fragments[i].getRequiredBundles();
for (int j = 0; j < fragmentRequiredBundles.length; j++) {
- if (resolved.contains(fragmentRequiredBundles[i].getSupplier())) {
- resolvedBundlesExported.put(fragmentRequiredBundles[i].getSupplier(), new Boolean(fragmentRequiredBundles[i].isExported()));
- resolved.remove(fragmentRequiredBundles[i].getSupplier());
+ if (resolved.contains(fragmentRequiredBundles[j].getSupplier())) {
+ resolvedBundlesExported.put(fragmentRequiredBundles[j].getSupplier(), new Boolean(fragmentRequiredBundles[j].isExported()));
+ resolved.remove(fragmentRequiredBundles[j].getSupplier());
}
}
if (resolved.size() == 0) {
diff --git a/bundles/org.eclipse.osgi/supplement/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi/supplement/META-INF/MANIFEST.MF
index d8ff0de..7267dde7 100644
--- a/bundles/org.eclipse.osgi/supplement/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.osgi/supplement/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.equinox.supplement
-Bundle-Version: 1.3.0.qualifier
+Bundle-Version: 1.3.100.qualifier
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Export-Package: org.eclipse.osgi.framework.log;version="1.0",
diff --git a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/util/SecureAction.java b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/util/SecureAction.java
index 7a25fb5..400218d 100644
--- a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/util/SecureAction.java
+++ b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/util/SecureAction.java
@@ -175,6 +175,29 @@
}
/**
+ * Returns the canonical path of a file. Same as calling
+ * file.getCanonicalPath().
+ * @param file a file object
+ * @return the canonical path of a file.
+ * @throws IOException on error
+ */
+ public String getCanonicalPath(final File file) throws IOException {
+ if (System.getSecurityManager() == null)
+ return file.getCanonicalPath();
+ try {
+ return (String) AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() throws IOException {
+ return file.getCanonicalPath();
+ }
+ }, controlContext);
+ } catch (PrivilegedActionException e) {
+ if (e.getException() instanceof IOException)
+ throw (IOException) e.getException();
+ throw (RuntimeException) e.getException();
+ }
+ }
+
+ /**
* Returns true if a file exists, otherwise false is returned. Same as calling
* file.exists().
* @param file a file object