diff options
author | Lukas Huser | 2013-12-05 10:54:47 +0000 |
---|---|---|
committer | Stephan Leicht Vogt | 2013-12-09 06:44:20 +0000 |
commit | b4145262d8c224d040e0252cca1e9b91e2a4968e (patch) | |
tree | 1fb60152c9dc115534c118efe3303e7fa92b8054 | |
parent | fac7d810f10c0561515f183675a6cdc9ad6d74f1 (diff) | |
download | org.eclipse.scout.rt-b4145262d8c224d040e0252cca1e9b91e2a4968e.tar.gz org.eclipse.scout.rt-b4145262d8c224d040e0252cca1e9b91e2a4968e.tar.xz org.eclipse.scout.rt-b4145262d8c224d040e0252cca1e9b91e2a4968e.zip |
Bug 422878 - [RWT] Cross domain scripting issue in RwtScoutBrowserField
https://bugs.eclipse.org/bugs/show_bug.cgi?id=422878
RwtScoutBrowserField: Dynamically attach and detach BrowserExtension to
avoid cross domain scripting issue.
[Rwt|Swt|Swing]ScoutBrowserField: Consistency between all UI specific
implementations: treat the "value" (a RemoteFile) and the "location" (an
external URL) as two separate attributes of the browser field, which can
be set independently.
Change-Id: Id9c80d00130a83e753691ee21911e9276bd85c76
Signed-off-by: Lukas Huser <lhu@bsiag.com>
Reviewed-on: https://git.eclipse.org/r/19365
Tested-by: Hudson CI
Reviewed-by: Stephan Leicht Vogt <stephan.leicht@bsiag.com>
IP-Clean: Stephan Leicht Vogt <stephan.leicht@bsiag.com>
3 files changed, 156 insertions, 81 deletions
diff --git a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/form/fields/browserfield/RwtScoutBrowserField.java b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/form/fields/browserfield/RwtScoutBrowserField.java index 4dada15e24..4928d86420 100644 --- a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/form/fields/browserfield/RwtScoutBrowserField.java +++ b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/form/fields/browserfield/RwtScoutBrowserField.java @@ -17,9 +17,11 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; +import java.net.URL; import java.util.concurrent.atomic.AtomicReference; import org.eclipse.scout.commons.IOUtility; +import org.eclipse.scout.commons.StringUtility; import org.eclipse.scout.commons.exception.ProcessingException; import org.eclipse.scout.commons.logger.IScoutLogger; import org.eclipse.scout.commons.logger.ScoutLogManager; @@ -41,13 +43,23 @@ import org.eclipse.swt.widgets.Composite; public class RwtScoutBrowserField extends RwtScoutValueFieldComposite<IBrowserField> implements IRwtScoutBrowserField { private static final IScoutLogger LOG = ScoutLogManager.getLogger(RwtScoutBrowserField.class); - private String m_currentLocation; private BrowserExtension m_browserExtension; public RwtScoutBrowserField() { } @Override + protected void attachScout() { + super.attachScout(); + // Super call invokes setValueFromScout. + // If both value and location are null we don't initialize it a second time. + // If location is set, it will win over value. + if (getScoutObject().getLocation() != null) { + setLocationFromScout(); + } + } + + @Override protected void initializeUi(Composite parent) { Composite container = getUiEnvironment().getFormToolkit().createComposite(parent); StatusLabelEx label = getUiEnvironment().getFormToolkit().createStatusLabel(container, getScoutObject()); @@ -55,29 +67,19 @@ public class RwtScoutBrowserField extends RwtScoutValueFieldComposite<IBrowserFi Browser browser = getUiEnvironment().getFormToolkit().createBrowser(container, SWT.NONE); setUiField(browser); - m_browserExtension = new BrowserExtension(browser, new IHyperlinkCallback() { - - @Override - public void execute(String url) { - getUiField().setUrl(url); - } - - }); - m_browserExtension.attach(); - browser.addDisposeListener(new DisposeListener() { - private static final long serialVersionUID = 1L; - - @Override - public void widgetDisposed(DisposeEvent e) { - m_browserExtension.detach(); - } - }); browser.addLocationListener(new LocationAdapter() { private static final long serialVersionUID = 1L; @Override public void changing(LocationEvent event) { - event.doit = fireBeforeLocationChangedFromUi(event.location); + boolean changeAccepted = fireBeforeLocationChangedFromUi(event.location); + if (changeAccepted) { + // check: from local to external location? + if (m_browserExtension != null && isExternalUrl(event.location)) { + detachBrowserExtension(); + } + } + event.doit = changeAccepted; } @Override @@ -93,6 +95,46 @@ public class RwtScoutBrowserField extends RwtScoutValueFieldComposite<IBrowserFi getUiContainer().setLayout(new LogicalGridLayout(1, 0)); } + protected boolean isExternalUrl(String location) { + boolean externalUrl = false; + try { + String host = new URL(location).getHost(); + externalUrl = StringUtility.hasText(host) && StringUtility.notEequalsIgnoreCase("local", host); + } + catch (Throwable t) { + // nop: externalUrl == false + } + return externalUrl; + } + + protected void attachBrowserExtension(Browser browser) { + detachBrowserExtension(); + final BrowserExtension browserExtension = new BrowserExtension(browser, new IHyperlinkCallback() { + + @Override + public void execute(String url) { + setLocationInternal(url); + } + }); + browserExtension.attach(); + browser.addDisposeListener(new DisposeListener() { + private static final long serialVersionUID = 1L; + + @Override + public void widgetDisposed(DisposeEvent e) { + browserExtension.detach(); + } + }); + m_browserExtension = browserExtension; + } + + protected void detachBrowserExtension() { + if (m_browserExtension != null) { + m_browserExtension.detach(); + m_browserExtension = null; + } + } + @Override public Browser getUiField() { return (Browser) super.getUiField(); @@ -106,25 +148,31 @@ public class RwtScoutBrowserField extends RwtScoutValueFieldComposite<IBrowserFi } } + protected void setLocationFromScout() { + setLocationInternal(getScoutObject().getLocation()); + } + @Override protected void setValueFromScout() { - setLocationFromScout(); - } + RemoteFile remoteFile = getScoutObject().getValue(); + String location = null; + if (remoteFile != null && remoteFile.exists()) { + if (m_browserExtension != null) { + m_browserExtension.clearResourceCache(); + m_browserExtension.clearLocalHyperlinkCache(); + } + else { + attachBrowserExtension(getUiField()); + } - protected void setLocationFromScout() { - m_browserExtension.clearResourceCache(); - m_browserExtension.clearLocalHyperlinkCache(); - String location = getScoutObject().getLocation(); - RemoteFile r = getScoutObject().getValue(); - if (location == null && r != null && r.exists()) { try { - if (r.getName().matches(".*\\.(zip|jar)")) { - location = registerResourcesInZip(r); + if (remoteFile.getName().matches(".*\\.(zip|jar)")) { + location = registerResourcesInZip(m_browserExtension, remoteFile); } else { - String content = IOUtility.getContent(r.getDecompressedReader()); + String content = IOUtility.getContent(remoteFile.getDecompressedReader()); content = m_browserExtension.adaptLocalHyperlinks(content); - location = m_browserExtension.addResource(r.getName(), new ByteArrayInputStream(content.getBytes("UTF-8"))); + location = m_browserExtension.addResource(remoteFile.getName(), new ByteArrayInputStream(content.getBytes("UTF-8"))); } //Prevent caching by making the request unique if (location != null) { @@ -132,19 +180,13 @@ public class RwtScoutBrowserField extends RwtScoutValueFieldComposite<IBrowserFi } } catch (Throwable t) { - LOG.error("preparing html content for " + r, t); + LOG.error("preparing html content for " + remoteFile, t); } } - m_currentLocation = location; - if (m_currentLocation != null) { - getUiField().setUrl(m_currentLocation); - } - else { - getUiField().setText(""); - } + setLocationInternal(location); } - private String registerResourcesInZip(RemoteFile zipFile) throws ProcessingException, IOException, UnsupportedEncodingException, FileNotFoundException { + private String registerResourcesInZip(BrowserExtension browserExtension, RemoteFile zipFile) throws ProcessingException, IOException, UnsupportedEncodingException, FileNotFoundException { String location = null; File tempDir = IOUtility.createTempDirectory("browser"); try { @@ -157,22 +199,22 @@ public class RwtScoutBrowserField extends RwtScoutValueFieldComposite<IBrowserFi String path = f.getAbsolutePath().substring(prefixLen); if (path.toLowerCase().matches(".*\\.(htm|html)")) { String content = IOUtility.getContent(new InputStreamReader(new FileInputStream(f), "UTF-8")); - content = m_browserExtension.adaptLocalHyperlinks(content); + content = browserExtension.adaptLocalHyperlinks(content); if (location == null && path.startsWith(simpleName)) { //this is the index.html - location = m_browserExtension.addResource(simpleName, new ByteArrayInputStream(content.getBytes("UTF-8"))); + location = browserExtension.addResource(simpleName, new ByteArrayInputStream(content.getBytes("UTF-8"))); } else { - m_browserExtension.addResource(path, new ByteArrayInputStream(content.getBytes("UTF-8"))); + browserExtension.addResource(path, new ByteArrayInputStream(content.getBytes("UTF-8"))); } } else if (path.toLowerCase().matches(".*\\.(svg)")) { String content = IOUtility.getContent(new InputStreamReader(new FileInputStream(f))); - content = m_browserExtension.adaptLocalHyperlinks(content); - m_browserExtension.addResource(path, new ByteArrayInputStream(content.getBytes("UTF-8"))); + content = browserExtension.adaptLocalHyperlinks(content); + browserExtension.addResource(path, new ByteArrayInputStream(content.getBytes("UTF-8"))); } else { - m_browserExtension.addResource(path, new FileInputStream(f)); + browserExtension.addResource(path, new FileInputStream(f)); } } } @@ -185,6 +227,15 @@ public class RwtScoutBrowserField extends RwtScoutValueFieldComposite<IBrowserFi return location; } + protected void setLocationInternal(String location) { + if (StringUtility.hasText(location)) { + getUiField().setUrl(location); + } + else { + getUiField().setText(""); + } + } + @Override protected void setEnabledFromScout(boolean b) { //nop diff --git a/org.eclipse.scout.rt.ui.swing.browser.swt.fragment/src/org/eclipse/scout/rt/ui/swing/form/fields/browserfield/internal/SwingScoutBrowserField.java b/org.eclipse.scout.rt.ui.swing.browser.swt.fragment/src/org/eclipse/scout/rt/ui/swing/form/fields/browserfield/internal/SwingScoutBrowserField.java index b3936f2e8c..a14f0b4641 100644 --- a/org.eclipse.scout.rt.ui.swing.browser.swt.fragment/src/org/eclipse/scout/rt/ui/swing/form/fields/browserfield/internal/SwingScoutBrowserField.java +++ b/org.eclipse.scout.rt.ui.swing.browser.swt.fragment/src/org/eclipse/scout/rt/ui/swing/form/fields/browserfield/internal/SwingScoutBrowserField.java @@ -15,6 +15,7 @@ import java.util.concurrent.atomic.AtomicReference; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.scout.commons.IOUtility; import org.eclipse.scout.commons.RunnableWithException; +import org.eclipse.scout.commons.StringUtility; import org.eclipse.scout.commons.exception.ProcessingException; import org.eclipse.scout.commons.logger.IScoutLogger; import org.eclipse.scout.commons.logger.ScoutLogManager; @@ -51,7 +52,6 @@ public class SwingScoutBrowserField extends SwingScoutValueFieldComposite<IBrows private Shell m_swtShell; private Browser m_swtBrowser; private File m_tempDir; - private String m_currentLocation; // private final List<RunnableWithException<?>> m_swtCommandQueue; private final Object m_swtCommandQueueLock; @@ -96,6 +96,13 @@ public class SwingScoutBrowserField extends SwingScoutValueFieldComposite<IBrows @Override protected void attachScout() { super.attachScout(); + // Super call invokes setValueFromScout. + // If both value and location are null we don't initialize it a second time. + // If location is set, it will win over value. + if (getScoutObject().getLocation() != null) { + setLocationFromScout(); + } + if (m_hierarchyListener == null) { m_hierarchyListener = new P_HierarchyListener(); m_canvas.addHierarchyListener(m_hierarchyListener); @@ -150,7 +157,7 @@ public class SwingScoutBrowserField extends SwingScoutValueFieldComposite<IBrows installMouseListener(); } catch (Exception e) { - LOG.error("Unexpected error occured while attaching Microsoft Word. All resources safely disposed.", e); + LOG.error("Unexpected error occured while attaching SWT Browser. All resources safely disposed.", e); detachSwtSafe(); } finally { @@ -248,15 +255,15 @@ public class SwingScoutBrowserField extends SwingScoutValueFieldComposite<IBrows } } - @Override - protected void setValueFromScout(Object o) { - setLocationFromScout(); + protected void setLocationFromScout() { + setLocationInternal(getScoutObject().getLocation()); } - protected void setLocationFromScout() { - String location = getScoutObject().getLocation(); - RemoteFile r = getScoutObject().getValue(); - if (location == null && r != null && r.exists()) { + @Override + protected void setValueFromScout(Object o) { + RemoteFile remoteFile = getScoutObject().getValue(); + String location = null; + if (remoteFile != null && remoteFile.exists()) { try { if (m_tempDir == null) { try { @@ -266,9 +273,9 @@ public class SwingScoutBrowserField extends SwingScoutValueFieldComposite<IBrows LOG.error("create temporary folder", e); } } - if (r.getName().matches(".*\\.(zip|jar)")) { - r.writeZipContentToDirectory(m_tempDir); - String simpleName = r.getName().replaceAll("\\.(zip|jar)", ".htm"); + if (remoteFile.getName().matches(".*\\.(zip|jar)")) { + remoteFile.writeZipContentToDirectory(m_tempDir); + String simpleName = remoteFile.getName().replaceAll("\\.(zip|jar)", ".htm"); for (File f : m_tempDir.listFiles()) { if (f.getName().startsWith(simpleName)) { location = f.toURI().toURL().toExternalForm(); @@ -277,22 +284,25 @@ public class SwingScoutBrowserField extends SwingScoutValueFieldComposite<IBrows } } else { - File f = new File(m_tempDir, r.getName()); - r.writeData(f); + File f = new File(m_tempDir, remoteFile.getName()); + remoteFile.writeData(f); location = f.toURI().toURL().toExternalForm(); } } catch (Throwable t) { - LOG.error("preparing html content for " + r, t); + LOG.error("preparing html content for " + remoteFile, t); } } - m_currentLocation = location; + setLocationInternal(location); + } + + protected void setLocationInternal(final String location) { //post the document to swt swtAsyncExec(new RunnableWithException<Object>() { @Override public Object run() throws Throwable { - if (m_currentLocation != null) { - getSwtBrowser().setUrl(m_currentLocation); + if (StringUtility.hasText(location)) { + getSwtBrowser().setUrl(location); } else { getSwtBrowser().setText(""); diff --git a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/browserfield/SwtScoutBrowserField.java b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/browserfield/SwtScoutBrowserField.java index f9140e5c23..9b8794629e 100644 --- a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/browserfield/SwtScoutBrowserField.java +++ b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/browserfield/SwtScoutBrowserField.java @@ -14,6 +14,7 @@ import java.io.File; import java.util.concurrent.atomic.AtomicReference; import org.eclipse.scout.commons.IOUtility; +import org.eclipse.scout.commons.StringUtility; import org.eclipse.scout.commons.exception.ProcessingException; import org.eclipse.scout.commons.logger.IScoutLogger; import org.eclipse.scout.commons.logger.ScoutLogManager; @@ -34,7 +35,6 @@ public class SwtScoutBrowserField extends SwtScoutValueFieldComposite<IBrowserFi private static final IScoutLogger LOG = ScoutLogManager.getLogger(SwtScoutBrowserField.class); private File m_tempDir; - private String m_currentLocation; public SwtScoutBrowserField() { } @@ -44,6 +44,17 @@ public class SwtScoutBrowserField extends SwtScoutValueFieldComposite<IBrowserFi } @Override + protected void attachScout() { + super.attachScout(); + // Super call invokes setValueFromScout. + // If both value and location are null we don't initialize it a second time. + // If location is set, it will win over value. + if (getScoutObject().getLocation() != null) { + setLocationFromScout(); + } + } + + @Override protected void initializeSwt(Composite parent) { Composite container = getEnvironment().getFormToolkit().createComposite(parent); StatusLabelEx label = getEnvironment().getFormToolkit().createStatusLabel(container, getEnvironment(), getScoutObject()); @@ -99,15 +110,15 @@ public class SwtScoutBrowserField extends SwtScoutValueFieldComposite<IBrowserFi } } - @Override - protected void setValueFromScout() { - setLocationFromScout(); + protected void setLocationFromScout() { + setLocationInternal(getScoutObject().getLocation()); } - protected void setLocationFromScout() { - String location = getScoutObject().getLocation(); - RemoteFile r = getScoutObject().getValue(); - if (location == null && r != null && r.exists()) { + @Override + protected void setValueFromScout() { + RemoteFile remoteFile = getScoutObject().getValue(); + String location = null; + if (remoteFile != null && remoteFile.exists()) { try { if (m_tempDir == null) { try { @@ -117,9 +128,9 @@ public class SwtScoutBrowserField extends SwtScoutValueFieldComposite<IBrowserFi LOG.error("create temporary folder", e); } } - if (r.getName().matches(".*\\.(zip|jar)")) { - r.writeZipContentToDirectory(m_tempDir); - String simpleName = r.getName().replaceAll("\\.(zip|jar)", ".htm"); + if (remoteFile.getName().matches(".*\\.(zip|jar)")) { + remoteFile.writeZipContentToDirectory(m_tempDir); + String simpleName = remoteFile.getName().replaceAll("\\.(zip|jar)", ".htm"); for (File f : m_tempDir.listFiles()) { if (f.getName().startsWith(simpleName)) { location = f.toURI().toURL().toExternalForm(); @@ -128,18 +139,21 @@ public class SwtScoutBrowserField extends SwtScoutValueFieldComposite<IBrowserFi } } else { - File f = new File(m_tempDir, r.getName()); - r.writeData(f); + File f = new File(m_tempDir, remoteFile.getName()); + remoteFile.writeData(f); location = f.toURI().toURL().toExternalForm(); } } catch (Throwable t) { - LOG.error("preparing html content for " + r, t); + LOG.error("preparing html content for " + remoteFile, t); } } - m_currentLocation = location; - if (m_currentLocation != null) { - getSwtField().setUrl(m_currentLocation); + setLocationInternal(location); + } + + protected void setLocationInternal(String location) { + if (StringUtility.hasText(location)) { + getSwtField().setUrl(location); } else { getSwtField().setText(""); |