ACS-10087 ATS Inconsistent behavior transforming corrupted docx document (#1150)

This commit is contained in:
Arindam Roy
2025-10-28 15:25:47 +05:30
committed by GitHub
parent a232be19c5
commit 0df5c18254
6 changed files with 107 additions and 1 deletions
@@ -42,6 +42,7 @@ import java.util.stream.Collectors;
import jakarta.jms.Destination;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.HttpStatus;
import org.springframework.web.multipart.MultipartFile;
import org.alfresco.transform.base.CustomTransformer;
@@ -51,6 +52,7 @@ import org.alfresco.transform.base.probes.ProbeTransform;
import org.alfresco.transform.base.registry.CustomTransformers;
import org.alfresco.transform.client.model.TransformRequest;
import org.alfresco.transform.common.TransformerDebug;
import org.alfresco.transform.common.TransformerMessages;
import org.alfresco.transform.exceptions.TransformException;
import org.alfresco.transform.registry.TransformServiceRegistry;
@@ -163,12 +165,27 @@ abstract class ProcessHandler extends FragmentHandler
@Override
public void onSuccessfulTransform()
{
validateOutputLength();
sendTransformResponse(transformManager);
LogEntry.setTargetSize(transformManager.getOutputLength());
LogEntry.setStatusCodeAndMessage(OK, "Success");
}
/**
* Checks whether the output file has zero length, although the input file has a non-zero length. This scenario happens when the source file is corrupted.
*/
private void validateOutputLength()
{
long sourceLen = getSourceSize();
long targetLen = transformManager.getOutputLength();
if (sourceLen > 0 && targetLen <= 0)
{
transformerDebug.logFailure(reference, TransformerMessages.CORRUPTED_FILE_ERROR);
throw new TransformException(HttpStatus.UNPROCESSABLE_ENTITY, TransformerMessages.CORRUPTED_FILE_ERROR);
}
}
protected void sendTransformResponse(TransformManagerImpl transformManager)
{}
@@ -2,7 +2,7 @@
* #%L
* Alfresco Transform Core
* %%
* Copyright (C) 2005 - 2021 Alfresco Software Limited
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
@@ -29,6 +29,7 @@ package org.alfresco.transform.tika;
import static java.text.MessageFormat.format;
import static java.util.function.Function.identity;
import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import static org.springframework.http.HttpStatus.OK;
@@ -41,9 +42,12 @@ import org.apache.commons.lang3.tuple.Triple;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.HttpClientErrorException;
import org.alfresco.transform.base.clients.HttpClient;
import org.alfresco.transform.common.TransformerMessages;
/**
* @author Cezar Leahu
@@ -164,4 +168,52 @@ public class TikaTransformationIT
allTargets("quick.tar.gz", "application/x-gzip"))
.flatMap(identity());
}
/**
* Tests that while transforming a corrupted file to txt format, exception is thrown.
*
* @param entry
* values to execute same test with different parameters.
*/
@ParameterizedTest
@MethodSource("engineTransformationsCorruptedToText")
public void testTransformationCorruptedToText(Triple<String, String, String> entry)
{
final String sourceFile = entry.getLeft();
final String sourceMimetype = entry.getRight();
final String targetExtension = entry.getMiddle();
String targetMimetype = extensionMimetype.get(targetExtension);
final String description = format("Transform ({0}, {1} -> {2}, {3})",
sourceFile, sourceMimetype, targetMimetype, targetExtension);
HttpClientErrorException expectedException = catchThrowableOfType(HttpClientErrorException.class, () -> {
HttpClient.sendTRequest(ENGINE_URL, sourceFile, null,
targetMimetype, targetExtension, ImmutableMap.of(
"targetEncoding", "UTF-8",
"sourceMimetype", sourceMimetype));
fail("Corrupted file should have thrown an exception");
});
assertThat(expectedException).as(description)
.hasMessageContaining(TransformerMessages.CORRUPTED_FILE_ERROR)
.extracting(HttpClientErrorException::getStatusCode)
.isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY);
}
private static Stream<Triple<String, String, String>> engineTransformationsCorruptedToText()
{
return Stream
.of(
textTargets("quick_corrupted.doc", "application/msword"),
textTargets("quick_corrupted.ppt", "application/vnd.ms-powerpoint"),
textTargets("quick_corrupted.pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"))
.flatMap(identity());
}
private static Stream<Triple<String, String, String>> textTargets(final String sourceFile,
final String sourceMimetype)
{
return Stream.of(Triple.of(sourceFile, "txt", sourceMimetype));
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,37 @@
/*
* #%L
* Alfresco Transform Model
* %%
* Copyright (C) 2025 Alfresco Software Limited
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-3.0.html>.
* #L%
*/
package org.alfresco.transform.common;
/**
* Holds definition of constants related to the Transformation messages.
*/
public class TransformerMessages
{
// Exceptions
public static final String CORRUPTED_FILE_ERROR = "The file after transformation is empty. This could be caused by a corrupted source file.";
/**
* Creates new instance of the class.
*/
private TransformerMessages()
{}
}