mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-10-08 14:51:49 +00:00
MNT-16381 Transformers must validate the content stream mimetype
- Addition of AbstractContentTransformer2.strictMimeTypeCheck(...) to check that the declared mimetype is the same as the Tika derived mimetype. Controlled by a new alfresco global property content.transformer.strict.mimetype.check (set to true by default). - Added the UnsupportedTransformationException to a number of transformation callers as they should have been handling it already. - Modified DifferrentMimeTypeTest to test the new strictMimeTypeCheck. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@128168 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -70,6 +70,7 @@ public abstract class AbstractContentTransformer2 extends AbstractContentTransfo
|
||||
private ContentTransformerRegistry registry;
|
||||
private boolean registerTransformer;
|
||||
private boolean retryTransformOnDifferentMimeType;
|
||||
private boolean strictMimeTypeCheck;
|
||||
MetadataExtracterConfig metadataExtracterConfig;
|
||||
/**
|
||||
* A flag that indicates that the transformer should be started in it own Thread so
|
||||
@@ -248,6 +249,11 @@ public abstract class AbstractContentTransformer2 extends AbstractContentTransfo
|
||||
targetMimetype, reader.getSize(), options);
|
||||
}
|
||||
|
||||
// MNT-16381: check the mimetype of the file supplied by the user
|
||||
// matches the sourceMimetype of the reader. Intermediate files are
|
||||
// not checked.
|
||||
strictMimeTypeCheck(reader, options);
|
||||
|
||||
// Check the transformability
|
||||
checkTransformable(reader, writer, options);
|
||||
|
||||
@@ -338,10 +344,10 @@ public abstract class AbstractContentTransformer2 extends AbstractContentTransfo
|
||||
String differentType = getMimetypeService().getMimetypeIfNotMatches(reader.getReader());
|
||||
|
||||
// Report the error
|
||||
if(differentType == null)
|
||||
if (differentType == null)
|
||||
{
|
||||
transformerDebug.debug(" Failed", e);
|
||||
throw new ContentIOException("Content conversion failed: \n" +
|
||||
transformerDebug.debug(" Failed", e);
|
||||
throw new ContentIOException("Content conversion failed: \n" +
|
||||
" reader: " + reader + "\n" +
|
||||
" writer: " + writer + "\n" +
|
||||
" options: " + options.toString(false) + "\n" +
|
||||
@@ -432,6 +438,26 @@ public abstract class AbstractContentTransformer2 extends AbstractContentTransfo
|
||||
}
|
||||
}
|
||||
|
||||
private void strictMimeTypeCheck(ContentReader reader, TransformationOptions options)
|
||||
throws UnsupportedTransformationException
|
||||
{
|
||||
if (strictMimeTypeCheck && depth.get() == 1)
|
||||
{
|
||||
String differentType = getMimetypeService().getMimetypeIfNotMatches(reader.getReader());
|
||||
if (differentType != null)
|
||||
{
|
||||
String fileName = transformerDebug.getFileName(options, true, 0);
|
||||
String readerSourceMimetype = reader.getMimetype();
|
||||
String message = "Transformation of ("+fileName+
|
||||
") has not taken place because the declared mimetype ("+
|
||||
readerSourceMimetype+") does not match the detected mimetype ("+
|
||||
differentType+").";
|
||||
logger.warn(message);
|
||||
throw new UnsupportedTransformationException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels <code>task</code> and closes content accessors
|
||||
*
|
||||
@@ -630,4 +656,14 @@ public abstract class AbstractContentTransformer2 extends AbstractContentTransfo
|
||||
{
|
||||
this.retryTransformOnDifferentMimeType = retryTransformOnDifferentMimeType;
|
||||
}
|
||||
|
||||
public boolean getStrictMimeTypeCheck()
|
||||
{
|
||||
return strictMimeTypeCheck;
|
||||
}
|
||||
|
||||
public void setStrictMimeTypeCheck(boolean strictMimeTypeCheck)
|
||||
{
|
||||
this.strictMimeTypeCheck = strictMimeTypeCheck;
|
||||
}
|
||||
}
|
||||
|
@@ -2675,45 +2675,14 @@ public class ScriptNode implements Scopeable, NamespacePrefixResolverProvider
|
||||
final NodeRef sourceNodeRef = nodeRef;
|
||||
|
||||
// the delegate definition for transforming a document
|
||||
Transformer transformer = new Transformer()
|
||||
Transformer transformer = new AbstractTransformer()
|
||||
{
|
||||
public ScriptNode transform(ContentService contentService, NodeRef nodeRef, ContentReader reader,
|
||||
ContentWriter writer)
|
||||
protected void doTransform(ContentService contentService,
|
||||
ContentReader reader, ContentWriter writer)
|
||||
{
|
||||
ScriptNode transformedNode = null;
|
||||
TransformationOptions options = new TransformationOptions();
|
||||
options.setSourceNodeRef(sourceNodeRef);
|
||||
|
||||
try
|
||||
{
|
||||
contentService.transform(reader, writer, options);
|
||||
transformedNode = newInstance(nodeRef, services, scope);
|
||||
}
|
||||
catch (NoTransformerException e)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
catch (AlfrescoRuntimeException e)
|
||||
{
|
||||
Throwable rootCause = ((AlfrescoRuntimeException)e).getRootCause();
|
||||
String message = rootCause.getMessage();
|
||||
message = message == null ? "" : message;
|
||||
if (rootCause instanceof UnimportantTransformException)
|
||||
{
|
||||
logger.debug(message);
|
||||
// ignore
|
||||
}
|
||||
else if (rootCause instanceof UnsupportedTransformationException)
|
||||
{
|
||||
logger.error(message);
|
||||
// ignore
|
||||
}
|
||||
else
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
return transformedNode;
|
||||
contentService.transform(reader, writer, options);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2828,10 +2797,10 @@ public class ScriptNode implements Scopeable, NamespacePrefixResolverProvider
|
||||
final NodeRef sourceNodeRef = nodeRef;
|
||||
|
||||
// the delegate definition for transforming an image
|
||||
Transformer transformer = new Transformer()
|
||||
Transformer transformer = new AbstractTransformer()
|
||||
{
|
||||
public ScriptNode transform(ContentService contentService, NodeRef nodeRef, ContentReader reader,
|
||||
ContentWriter writer)
|
||||
protected void doTransform(ContentService contentService,
|
||||
ContentReader reader, ContentWriter writer)
|
||||
{
|
||||
ImageTransformationOptions imageOptions = new ImageTransformationOptions();
|
||||
imageOptions.setSourceNodeRef(sourceNodeRef);
|
||||
@@ -2841,8 +2810,6 @@ public class ScriptNode implements Scopeable, NamespacePrefixResolverProvider
|
||||
imageOptions.setCommandOptions(options);
|
||||
}
|
||||
contentService.getImageTransformer().transform(reader, writer, imageOptions);
|
||||
|
||||
return newInstance(nodeRef, services, scope);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -4114,10 +4081,53 @@ public class ScriptNode implements Scopeable, NamespacePrefixResolverProvider
|
||||
*
|
||||
* @return Node representing the transformed entity
|
||||
*/
|
||||
ScriptNode transform(ContentService contentService, NodeRef noderef, ContentReader reader, ContentWriter writer);
|
||||
ScriptNode transform(ContentService contentService, NodeRef noderef,
|
||||
ContentReader reader, ContentWriter writer);
|
||||
}
|
||||
|
||||
|
||||
private abstract class AbstractTransformer implements Transformer
|
||||
{
|
||||
public ScriptNode transform(ContentService contentService, NodeRef nodeRef,
|
||||
ContentReader reader, ContentWriter writer)
|
||||
{
|
||||
ScriptNode transformedNode = null;
|
||||
|
||||
try
|
||||
{
|
||||
doTransform(contentService, reader, writer);
|
||||
transformedNode = newInstance(nodeRef, services, scope);
|
||||
}
|
||||
catch (NoTransformerException e)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
catch (AlfrescoRuntimeException e)
|
||||
{
|
||||
Throwable rootCause = ((AlfrescoRuntimeException)e).getRootCause();
|
||||
String message = rootCause.getMessage();
|
||||
message = message == null ? "" : message;
|
||||
if (rootCause instanceof UnimportantTransformException)
|
||||
{
|
||||
logger.debug(message);
|
||||
// ignore
|
||||
}
|
||||
else if (rootCause instanceof UnsupportedTransformationException)
|
||||
{
|
||||
logger.error(message);
|
||||
// ignore
|
||||
}
|
||||
else
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
return transformedNode;
|
||||
}
|
||||
|
||||
protected abstract void doTransform(ContentService contentService,
|
||||
ContentReader reader, ContentWriter writer);
|
||||
};
|
||||
|
||||
/**
|
||||
* NamespacePrefixResolverProvider getter implementation
|
||||
*/
|
||||
|
@@ -39,6 +39,7 @@ import org.alfresco.repo.action.ParameterDefinitionImpl;
|
||||
import org.alfresco.repo.content.transform.ContentTransformer;
|
||||
import org.alfresco.repo.content.transform.TransformerConfig;
|
||||
import org.alfresco.repo.content.transform.TransformerDebug;
|
||||
import org.alfresco.repo.content.transform.UnsupportedTransformationException;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.service.cmr.action.ActionServiceException;
|
||||
import org.alfresco.service.cmr.action.ActionTrackingService;
|
||||
@@ -446,7 +447,7 @@ public abstract class AbstractTransformationRenderingEngine extends AbstractRend
|
||||
contentService.transform(contentReader, tempContentWriter, options);
|
||||
return tempContentWriter;
|
||||
}
|
||||
catch (NoTransformerException ntx)
|
||||
catch (NoTransformerException|UnsupportedTransformationException ntx)
|
||||
{
|
||||
{
|
||||
logger.debug("No transformer found to execute rule: \n" + " reader: " + contentReader + "\n"
|
||||
|
@@ -54,6 +54,7 @@ import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.content.transform.ContentTransformer;
|
||||
import org.alfresco.repo.content.transform.TransformerDebug;
|
||||
import org.alfresco.repo.content.transform.UnsupportedTransformationException;
|
||||
import org.alfresco.repo.dictionary.IndexTokenisationMode;
|
||||
import org.alfresco.repo.search.AspectIndexFilter;
|
||||
import org.alfresco.repo.search.IndexerException;
|
||||
@@ -83,6 +84,7 @@ import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||
import org.alfresco.service.cmr.repository.MLText;
|
||||
import org.alfresco.service.cmr.repository.NoTransformerException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.Path;
|
||||
@@ -1573,7 +1575,7 @@ public class ADMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<NodeRef> imp
|
||||
+ " transformer: " + transformer + "\n" + " temp writer: " + writer);
|
||||
}
|
||||
}
|
||||
catch (ContentIOException e)
|
||||
catch (ContentIOException|NoTransformerException|UnsupportedTransformationException e)
|
||||
{
|
||||
// log it
|
||||
if (s_logger.isInfoEnabled())
|
||||
|
@@ -34,10 +34,9 @@ import java.util.Set;
|
||||
import org.alfresco.model.ApplicationModel;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.content.transform.UnsupportedTransformationException;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.model.FileNotFoundException;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
@@ -635,7 +634,7 @@ public abstract class BaseContentNode implements TemplateContent
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NoTransformerException e)
|
||||
catch (NoTransformerException|UnsupportedTransformationException e)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
Reference in New Issue
Block a user