From d0b5272b91857508b03ff8e803d349bcd3a3693f Mon Sep 17 00:00:00 2001 From: Kevin Roast Date: Fri, 9 Nov 2007 14:59:59 +0000 Subject: [PATCH] Sanitising of all java.net.URLEncoder class usage to use a proper UTF-8 URL encoder. Since URLEncoder is actually an HTML form encoder - not really for URI encoding - and it requires an extra step (converting '+' to %20) Replaced with w3 Consortium algorithm for fast UTF-8 URL encoding in a single step (rather than using the cludgy and slow URI core java classes) Addition of Template API for generate URLs to node content download webscript API: node.serviceUrl git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@7316 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../org/alfresco/repo/jscript/ScriptNode.java | 68 +++-------- .../repo/template/BaseContentNode.java | 113 ++++++++++-------- .../repo/template/UrlEncodeMethod.java | 17 +-- .../repo/template/VersionHistoryNode.java | 20 +--- 4 files changed, 88 insertions(+), 130 deletions(-) diff --git a/source/java/org/alfresco/repo/jscript/ScriptNode.java b/source/java/org/alfresco/repo/jscript/ScriptNode.java index 03ca401954..351467e6e2 100644 --- a/source/java/org/alfresco/repo/jscript/ScriptNode.java +++ b/source/java/org/alfresco/repo/jscript/ScriptNode.java @@ -28,8 +28,6 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.Serializable; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; import java.text.MessageFormat; import java.util.ArrayList; import java.util.HashMap; @@ -74,6 +72,7 @@ import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.util.GUID; import org.alfresco.util.ParameterCheck; +import org.alfresco.util.URLEncoder; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.mozilla.javascript.Context; @@ -82,7 +81,6 @@ import org.mozilla.javascript.ScriptableObject; import org.mozilla.javascript.UniqueTag; import org.mozilla.javascript.Wrapper; import org.springframework.util.FileCopyUtils; -import org.springframework.util.StringUtils; /** * Node class implementation, specific for use by ScriptService as part of the object model. @@ -861,16 +859,9 @@ public class ScriptNode implements Serializable, Scopeable { if (getIsDocument() == true) { - try - { - return MessageFormat.format(CONTENT_DEFAULT_URL, new Object[] { nodeRef.getStoreRef().getProtocol(), - nodeRef.getStoreRef().getIdentifier(), nodeRef.getId(), - StringUtils.replace(URLEncoder.encode(getName(), "UTF-8"), "+", "%20") }); - } - catch (UnsupportedEncodingException err) - { - throw new AlfrescoRuntimeException("Failed to encode content URL for node: " + nodeRef, err); - } + return MessageFormat.format(CONTENT_DEFAULT_URL, new Object[] { nodeRef.getStoreRef().getProtocol(), + nodeRef.getStoreRef().getIdentifier(), nodeRef.getId(), + URLEncoder.encode(getName())}); } else { @@ -894,18 +885,11 @@ public class ScriptNode implements Serializable, Scopeable { if (getIsDocument() == true) { - try - { - return MessageFormat.format(CONTENT_DOWNLOAD_URL, new Object[] { - nodeRef.getStoreRef().getProtocol(), - nodeRef.getStoreRef().getIdentifier(), - nodeRef.getId(), - StringUtils.replace(URLEncoder.encode(getName(), "UTF-8"), "+", "%20") }); - } - catch (UnsupportedEncodingException err) - { - throw new AlfrescoRuntimeException("Failed to encode content download URL for node: " + nodeRef, err); - } + return MessageFormat.format(CONTENT_DOWNLOAD_URL, new Object[] { + nodeRef.getStoreRef().getProtocol(), + nodeRef.getStoreRef().getIdentifier(), + nodeRef.getId(), + URLEncoder.encode(getName()) }); } else { @@ -2308,17 +2292,10 @@ public class ScriptNode implements Serializable, Scopeable */ public String getUrl() { - try - { - return MessageFormat.format(CONTENT_PROP_URL, new Object[] { nodeRef.getStoreRef().getProtocol(), - nodeRef.getStoreRef().getIdentifier(), nodeRef.getId(), - StringUtils.replace(URLEncoder.encode(getName(), "UTF-8"), "+", "%20"), - StringUtils.replace(URLEncoder.encode(property.toString(), "UTF-8"), "+", "%20") }); - } - catch (UnsupportedEncodingException err) - { - throw new AlfrescoRuntimeException("Failed to encode content URL for node: " + nodeRef, err); - } + return MessageFormat.format(CONTENT_PROP_URL, new Object[] { nodeRef.getStoreRef().getProtocol(), + nodeRef.getStoreRef().getIdentifier(), nodeRef.getId(), + URLEncoder.encode(getName()), + URLEncoder.encode(property.toString()) }); } public String jsGet_url() @@ -2333,19 +2310,12 @@ public class ScriptNode implements Serializable, Scopeable { if (getIsDocument() == true) { - try - { - return MessageFormat.format(CONTENT_DOWNLOAD_PROP_URL, new Object[] { - nodeRef.getStoreRef().getProtocol(), - nodeRef.getStoreRef().getIdentifier(), - nodeRef.getId(), - StringUtils.replace(URLEncoder.encode(getName(), "UTF-8"), "+", "%20"), - StringUtils.replace(URLEncoder.encode(property.toString(), "UTF-8"), "+", "%20") }); - } - catch (UnsupportedEncodingException err) - { - throw new AlfrescoRuntimeException("Failed to encode content download URL for node: " + nodeRef, err); - } + return MessageFormat.format(CONTENT_DOWNLOAD_PROP_URL, new Object[] { + nodeRef.getStoreRef().getProtocol(), + nodeRef.getStoreRef().getIdentifier(), + nodeRef.getId(), + URLEncoder.encode(getName()), + URLEncoder.encode(property.toString()) }); } else { diff --git a/source/java/org/alfresco/repo/template/BaseContentNode.java b/source/java/org/alfresco/repo/template/BaseContentNode.java index f8ca1eb9ab..4ab2d9ee87 100644 --- a/source/java/org/alfresco/repo/template/BaseContentNode.java +++ b/source/java/org/alfresco/repo/template/BaseContentNode.java @@ -25,8 +25,6 @@ package org.alfresco.repo.template; import java.io.Serializable; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; @@ -45,10 +43,9 @@ import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.FileTypeImageSize; -import org.alfresco.service.cmr.repository.TemplateException; import org.alfresco.service.cmr.repository.TemplateImageResolver; import org.alfresco.service.namespace.QName; -import org.springframework.util.StringUtils; +import org.alfresco.util.URLEncoder; /** * Base class for Template API objects that supply content functionality. @@ -58,9 +55,11 @@ import org.springframework.util.StringUtils; public abstract class BaseContentNode implements TemplateContent { protected final static String CONTENT_GET_URL = "/d/d/{0}/{1}/{2}/{3}"; - protected final static String CONTENT_DOWNLOAD_URL = "/d/a/{0}/{1}/{2}/{3}"; protected final static String CONTENT_GET_PROP_URL = "/d/d/{0}/{1}/{2}/{3}?property={4}"; + protected final static String CONTENT_DOWNLOAD_URL = "/d/a/{0}/{1}/{2}/{3}"; protected final static String CONTENT_DOWNLOAD_PROP_URL = "/d/a/{0}/{1}/{2}/{3}?property={4}"; + protected final static String CONTENT_SERVICE_GET_URL = "/api/node/content/{0}/{1}/{2}/{3}"; + protected final static String CONTENT_SERVICE_GET_PROP_URL = "/api/node/content;{4}/{0}/{1}/{2}/{3}"; protected final static String FOLDER_BROWSE_URL = "/n/browse/{0}/{1}/{2}"; protected final static String NAMESPACE_BEGIN = "" + QName.NAMESPACE_BEGIN; @@ -359,18 +358,8 @@ public abstract class BaseContentNode implements TemplateContent { if (getIsDocument() == true) { - try - { - return MessageFormat.format(CONTENT_GET_URL, new Object[] { - getNodeRef().getStoreRef().getProtocol(), - getNodeRef().getStoreRef().getIdentifier(), - getNodeRef().getId(), - StringUtils.replace(URLEncoder.encode(getName(), "UTF-8"), "+", "%20") } ); - } - catch (UnsupportedEncodingException err) - { - throw new TemplateException("Failed to encode content URL for node: " + getNodeRef(), err); - } + TemplateContentData content = (TemplateContentData)this.getProperties().get(ContentModel.PROP_CONTENT); + return content != null ? content.getUrl() : ""; } else { @@ -391,18 +380,21 @@ public abstract class BaseContentNode implements TemplateContent { if (getIsDocument() == true) { - try - { - return MessageFormat.format(CONTENT_DOWNLOAD_URL, new Object[] { - getNodeRef().getStoreRef().getProtocol(), - getNodeRef().getStoreRef().getIdentifier(), - getNodeRef().getId(), - StringUtils.replace(URLEncoder.encode(getName(), "UTF-8"), "+", "%20") }); - } - catch (UnsupportedEncodingException err) - { - throw new TemplateException("Failed to encode content download URL for node: " + getNodeRef(), err); - } + TemplateContentData content = (TemplateContentData)this.getProperties().get(ContentModel.PROP_CONTENT); + return content != null ? content.getDownloadUrl() : ""; + } + else + { + return ""; + } + } + + public String getServiceUrl() + { + if (getIsDocument() == true) + { + TemplateContentData content = (TemplateContentData)this.getProperties().get(ContentModel.PROP_CONTENT); + return content != null ? content.getServiceUrl() : ""; } else { @@ -428,7 +420,7 @@ public abstract class BaseContentNode implements TemplateContent for (int i=1; i