diff options
author | adheli.tavares <adheli.tavares@est.tech> | 2022-05-12 13:58:48 +0100 |
---|---|---|
committer | adheli.tavares <adheli.tavares@est.tech> | 2022-05-12 15:25:14 +0100 |
commit | 2a58e25bee3bf029e1696a443f23495e119c5855 (patch) | |
tree | cdb4ff9f1113251f0ea3a5ad7c667cfd0452c665 /plugins/reception-plugins/src/main | |
parent | 1537b4665f9050bb2efe6f4f0aba2fb38d52a0ef (diff) |
Security issues from sonar cloud fixes
Issue-ID: POLICY-4168
Change-Id: Iedac6c95be452be81e8c73055193b4707735ef56
Signed-off-by: adheli.tavares <adheli.tavares@est.tech>
Diffstat (limited to 'plugins/reception-plugins/src/main')
4 files changed, 160 insertions, 119 deletions
diff --git a/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/decoding/policy/file/AutomationCompositionDecoderFileInCsar.java b/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/decoding/policy/file/AutomationCompositionDecoderFileInCsar.java index fb7a8d99..7087d7ca 100644 --- a/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/decoding/policy/file/AutomationCompositionDecoderFileInCsar.java +++ b/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/decoding/policy/file/AutomationCompositionDecoderFileInCsar.java @@ -20,14 +20,10 @@ package org.onap.policy.distribution.reception.decoding.policy.file; -import java.io.IOException; import java.util.ArrayList; import java.util.Collection; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; +import java.util.HashMap; +import java.util.Map; import org.onap.policy.common.parameters.ParameterService; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.distribution.model.Csar; @@ -72,53 +68,28 @@ public class AutomationCompositionDecoderFileInCsar implements PolicyDecoder<Csa public Collection<ToscaEntity> decode(final Csar csar) throws PolicyDecodingException { final Collection<ToscaEntity> automationCompositionList = new ArrayList<>(); - try (var zipFile = new ZipFile(csar.getCsarFilePath())) { - final List<? extends ZipEntry> entries = zipFile.stream() - .filter(entry -> entry.getName().contains(decoderParameters.getAutomationCompositionType())) - .collect(Collectors.toList()); - - for (ZipEntry entry : entries) { - ReceptionUtil.validateZipEntry(entry.getName(), csar.getCsarFilePath(), entry.getSize()); - final ToscaServiceTemplate automationComposition = ReceptionUtil.decodeFile(zipFile, entry); + try { + Map<String, ToscaServiceTemplate> templates = new HashMap<>(); + ReceptionUtil.unzip(csar.getCsarFilePath(), templates, + decoderParameters.getAutomationCompositionType(), NODE_TYPES, DATA_TYPES); - if (null != automationComposition.getToscaTopologyTemplate()) { - validateTypes(zipFile, NODE_TYPES) - .ifPresent(node -> automationComposition.setNodeTypes(node.getNodeTypes())); + var node = templates.get(NODE_TYPES); + var data = templates.get(DATA_TYPES); - validateTypes(zipFile, DATA_TYPES) - .ifPresent(data -> automationComposition.setDataTypes(data.getDataTypes())); + templates.forEach((entry, t) -> { + if (entry.contains(decoderParameters.getAutomationCompositionType()) + && t.getToscaTopologyTemplate() != null) { + t.setNodeTypes(node != null ? node.getNodeTypes() : null); + t.setDataTypes(data != null ? data.getDataTypes() : null); - automationCompositionList.add(automationComposition); + automationCompositionList.add(t); } - } - } catch (final IOException | CoderException exp) { + }); + + } catch (final CoderException exp) { throw new PolicyDecodingException("Failed decoding the acm", exp); } return automationCompositionList; } - - /** - * Decode and validate if node or data type is available withing ACM csar file. - * - * @param zipFile full csar file - * @return tosca template with parsed node/data type - * @throws CoderException if file can't be parsed - */ - private Optional<ToscaServiceTemplate> validateTypes(final ZipFile zipFile, String type) - throws CoderException { - - try { - ToscaServiceTemplate template = null; - final Optional<? extends ZipEntry> file = zipFile.stream() - .filter(entry -> entry.getName().contains(type)).findFirst(); - - if (file.isPresent()) { - template = ReceptionUtil.decodeFile(zipFile, file.get()); - } - return Optional.ofNullable(template); - } catch (final IOException | CoderException exp) { - throw new CoderException("Couldn't decode " + type + " type", exp); - } - } } diff --git a/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/decoding/policy/file/PolicyDecoderFileInCsarToPolicy.java b/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/decoding/policy/file/PolicyDecoderFileInCsarToPolicy.java index 8d0a554a..86f857a8 100644 --- a/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/decoding/policy/file/PolicyDecoderFileInCsarToPolicy.java +++ b/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/decoding/policy/file/PolicyDecoderFileInCsarToPolicy.java @@ -23,13 +23,10 @@ package org.onap.policy.distribution.reception.decoding.policy.file; -import java.io.IOException; import java.util.ArrayList; import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; +import java.util.HashMap; +import java.util.Map; import org.onap.policy.common.parameters.ParameterService; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.distribution.model.Csar; @@ -70,19 +67,15 @@ public class PolicyDecoderFileInCsarToPolicy implements PolicyDecoder<Csar, Tosc */ @Override public Collection<ToscaEntity> decode(final Csar csar) throws PolicyDecodingException { - final Collection<ToscaEntity> policyList = new ArrayList<>(); + final Collection<ToscaEntity> policyList; - try (var zipFile = new ZipFile(csar.getCsarFilePath())) { - final List<? extends ZipEntry> entries = zipFile.stream() - .filter(entry -> entry.getName().contains(decoderParameters.getPolicyTypeFileName()) - || entry.getName().contains(decoderParameters.getPolicyFileName())).collect(Collectors.toList()); + try { + Map<String, ToscaServiceTemplate> templates = new HashMap<>(); + ReceptionUtil.unzip(csar.getCsarFilePath(), templates, decoderParameters.getPolicyFileName(), + decoderParameters.getPolicyTypeFileName()); + policyList = new ArrayList<>(templates.values()); - for (ZipEntry entry : entries) { - ReceptionUtil.validateZipEntry(entry.getName(), csar.getCsarFilePath(), entry.getSize()); - final ToscaServiceTemplate policy = ReceptionUtil.decodeFile(zipFile, entry); - policyList.add(policy); - } - } catch (final IOException | CoderException exp) { + } catch (final CoderException exp) { throw new PolicyDecodingException("Failed decoding the policy", exp); } diff --git a/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/handling/sdc/SdcReceptionHandler.java b/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/handling/sdc/SdcReceptionHandler.java index 5fd76bea..ff915613 100644 --- a/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/handling/sdc/SdcReceptionHandler.java +++ b/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/handling/sdc/SdcReceptionHandler.java @@ -1,7 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2018 Ericsson. All rights reserved. - * Copyright (C) 2019 Nordix Foundation. + * Copyright (C) 2019, 2022 Nordix Foundation. * Modifications Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved. * Modifications Copyright (C) 2021 Bell Canada. All rights reserved. * ================================================================================ @@ -28,6 +28,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Optional; import java.util.concurrent.atomic.AtomicInteger; import org.onap.policy.common.parameters.ParameterService; import org.onap.policy.distribution.model.Csar; @@ -62,7 +63,7 @@ public class SdcReceptionHandler extends AbstractReceptionHandler implements INo private SdcReceptionHandlerStatus sdcReceptionHandlerStatus = SdcReceptionHandlerStatus.STOPPED; private IDistributionClient distributionClient; private SdcConfiguration sdcConfig; - private AtomicInteger nbOfNotificationsOngoing = new AtomicInteger(); + private final AtomicInteger nbOfNotificationsOngoing = new AtomicInteger(); private int retryDelay; private SdcClientHandler sdcClientHandler; @@ -73,7 +74,7 @@ public class SdcReceptionHandler extends AbstractReceptionHandler implements INo @Override protected void initializeReception(final String parameterGroupName) { final SdcReceptionHandlerConfigurationParameterGroup handlerParameters = - ParameterService.get(parameterGroupName); + ParameterService.get(parameterGroupName); retryDelay = handlerParameters.getRetryDelay() < 30 ? 30 : handlerParameters.getRetryDelay(); sdcConfig = new SdcConfiguration(handlerParameters); distributionClient = createSdcDistributionClient(); @@ -101,7 +102,7 @@ public class SdcReceptionHandler extends AbstractReceptionHandler implements INo * * @param newStatus the new status */ - private final synchronized void changeSdcReceptionHandlerStatus(final SdcReceptionHandlerStatus newStatus) { + private synchronized void changeSdcReceptionHandlerStatus(final SdcReceptionHandlerStatus newStatus) { switch (newStatus) { case INIT: case STOPPED: @@ -130,7 +131,6 @@ public class SdcReceptionHandler extends AbstractReceptionHandler implements INo /** * Method to initialize the SDC client. - * */ protected void initializeSdcClient() { @@ -142,7 +142,7 @@ public class SdcReceptionHandler extends AbstractReceptionHandler implements INo final IDistributionClientResult clientResult = distributionClient.init(sdcConfig, this); if (!clientResult.getDistributionActionResult().equals(DistributionActionResultEnum.SUCCESS)) { LOGGER.error("SDC client initialization failed with reason: {}. Initialization will be retried after {} {}", - clientResult.getDistributionMessageResult(), retryDelay, SECONDS); + clientResult.getDistributionMessageResult(), retryDelay, SECONDS); return; } LOGGER.debug("SDC Client is initialized successfully"); @@ -151,7 +151,6 @@ public class SdcReceptionHandler extends AbstractReceptionHandler implements INo /** * Method to start the SDC client. - * */ protected void startSdcClient() { @@ -163,7 +162,7 @@ public class SdcReceptionHandler extends AbstractReceptionHandler implements INo final IDistributionClientResult clientResult = distributionClient.start(); if (!clientResult.getDistributionActionResult().equals(DistributionActionResultEnum.SUCCESS)) { LOGGER.error("SDC client start failed with reason: {}. Start will be retried after {} {}", - clientResult.getDistributionMessageResult(), retryDelay, SECONDS); + clientResult.getDistributionMessageResult(), retryDelay, SECONDS); return; } LOGGER.debug("SDC Client is started successfully"); @@ -173,14 +172,13 @@ public class SdcReceptionHandler extends AbstractReceptionHandler implements INo /** * Method to stop the SDC client. - * */ protected void stopSdcClient() { LOGGER.debug("Going to stop the SDC Client..."); final IDistributionClientResult clientResult = distributionClient.stop(); if (!clientResult.getDistributionActionResult().equals(DistributionActionResultEnum.SUCCESS)) { LOGGER.error("SDC client stop failed with reason: {}. Stop will be retried after {} {}", - clientResult.getDistributionMessageResult(), retryDelay, SECONDS); + clientResult.getDistributionMessageResult(), retryDelay, SECONDS); return; } LOGGER.debug("SDC Client is stopped successfully"); @@ -199,29 +197,29 @@ public class SdcReceptionHandler extends AbstractReceptionHandler implements INo for (final IArtifactInfo artifact : notificationData.getServiceArtifacts()) { try { final IDistributionClientDownloadResult resultArtifact = - downloadTheArtifact(artifact, notificationData); + downloadTheArtifact(artifact, notificationData); final var filePath = writeArtifactToFile(artifact, resultArtifact); final var csarObject = new Csar(filePath.toString()); inputReceived(csarObject); sendDistributionStatus(DistributionStatusType.DEPLOY, artifact.getArtifactURL(), - notificationData.getDistributionID(), DistributionStatusEnum.DEPLOY_OK, null); + notificationData.getDistributionID(), DistributionStatusEnum.DEPLOY_OK, null); deleteArtifactFile(filePath); } catch (final ArtifactDownloadException | PolicyDecodingException exp) { LOGGER.error("Failed to process csar service artifacts ", exp); artifactsProcessedSuccessfully = false; sendDistributionStatus(DistributionStatusType.DEPLOY, artifact.getArtifactURL(), - notificationData.getDistributionID(), DistributionStatusEnum.DEPLOY_ERROR, - "Failed to deploy the artifact due to: " + exp.getMessage()); + notificationData.getDistributionID(), DistributionStatusEnum.DEPLOY_ERROR, + "Failed to deploy the artifact due to: " + exp.getMessage()); } } if (artifactsProcessedSuccessfully) { DistributionStatisticsManager.updateDistributionSuccessCount(); sendComponentDoneStatus(notificationData.getDistributionID(), DistributionStatusEnum.COMPONENT_DONE_OK, - null); + null); } else { DistributionStatisticsManager.updateDistributionFailureCount(); sendComponentDoneStatus(notificationData.getDistributionID(), DistributionStatusEnum.COMPONENT_DONE_ERROR, - "Failed to process the artifact"); + "Failed to process the artifact"); } } @@ -233,38 +231,42 @@ public class SdcReceptionHandler extends AbstractReceptionHandler implements INo * @throws ArtifactDownloadException if download fails */ private IDistributionClientDownloadResult downloadTheArtifact(final IArtifactInfo artifact, - final INotificationData notificationData) throws ArtifactDownloadException { + final INotificationData notificationData) + throws ArtifactDownloadException { DistributionStatisticsManager.updateTotalDownloadCount(); final IDistributionClientDownloadResult downloadResult = distributionClient.download(artifact); if (!downloadResult.getDistributionActionResult().equals(DistributionActionResultEnum.SUCCESS)) { DistributionStatisticsManager.updateDownloadFailureCount(); final String message = "Failed to download artifact with name: " + artifact.getArtifactName() + " due to: " - + downloadResult.getDistributionMessageResult(); + + downloadResult.getDistributionMessageResult(); LOGGER.error(message); sendDistributionStatus(DistributionStatusType.DOWNLOAD, artifact.getArtifactURL(), - notificationData.getDistributionID(), DistributionStatusEnum.DOWNLOAD_ERROR, message); + notificationData.getDistributionID(), DistributionStatusEnum.DOWNLOAD_ERROR, message); throw new ArtifactDownloadException(message); } DistributionStatisticsManager.updateDownloadSuccessCount(); sendDistributionStatus(DistributionStatusType.DOWNLOAD, artifact.getArtifactURL(), - notificationData.getDistributionID(), DistributionStatusEnum.DOWNLOAD_OK, null); + notificationData.getDistributionID(), DistributionStatusEnum.DOWNLOAD_OK, null); return downloadResult; } /** * Method to write the downloaded distribution artifact to local file system. * - * @param artifact the notification artifact + * @param artifact the notification artifact * @param resultArtifact the download result artifact * @return the local path of written file * @throws ArtifactDownloadException if error occurs while writing the artifact */ private Path writeArtifactToFile(final IArtifactInfo artifact, - final IDistributionClientDownloadResult resultArtifact) throws ArtifactDownloadException { + final IDistributionClientDownloadResult resultArtifact) + throws ArtifactDownloadException { try { final byte[] payloadBytes = resultArtifact.getArtifactPayload(); - final var tempArtifactFile = File.createTempFile(artifact.getArtifactName(), ".csar"); + + final var tempArtifactFile = Optional.ofNullable(safelyCreateFile(artifact.getArtifactName())) + .orElseThrow(() -> new ArtifactDownloadException("Failed to create temporary file.")); try (var fileOutputStream = new FileOutputStream(tempArtifactFile)) { fileOutputStream.write(payloadBytes, 0, payloadBytes.length); return tempArtifactFile.toPath(); @@ -290,19 +292,20 @@ public class SdcReceptionHandler extends AbstractReceptionHandler implements INo /** * Sends the distribution status to SDC using the input values. * - * @param statusType the status type - * @param artifactUrl the artifact url + * @param statusType the status type + * @param artifactUrl the artifact url * @param distributionId the distribution id - * @param status the status - * @param errorReason the error reason + * @param status the status + * @param errorReason the error reason */ private void sendDistributionStatus(final DistributionStatusType statusType, final String artifactUrl, - final String distributionId, final DistributionStatusEnum status, final String errorReason) { + final String distributionId, final DistributionStatusEnum status, + final String errorReason) { IDistributionClientResult clientResult; final IDistributionStatusMessage message = DistributionStatusMessage.builder().artifactUrl(artifactUrl) - .consumerId(sdcConfig.getConsumerID()).distributionId(distributionId).distributionStatus(status) - .timestamp(System.currentTimeMillis()).build(); + .consumerId(sdcConfig.getConsumerID()).distributionId(distributionId).distributionStatus(status) + .timestamp(System.currentTimeMillis()).build(); if (DistributionStatusType.DOWNLOAD.equals(statusType)) { if (errorReason != null) { clientResult = distributionClient.sendDownloadStatus(message, errorReason); @@ -318,8 +321,8 @@ public class SdcReceptionHandler extends AbstractReceptionHandler implements INo } final var loggerMessage = new StringBuilder(); loggerMessage.append("distribution status to SDC with values - ").append("DistributionId") - .append(distributionId).append(" Artifact: ").append(artifactUrl).append(" StatusType: ") - .append(statusType.name()).append(" Status: ").append(status.name()); + .append(distributionId).append(" Artifact: ").append(artifactUrl).append(" StatusType: ") + .append(statusType.name()).append(" Status: ").append(status.name()); if (errorReason != null) { loggerMessage.append(" ErrorReason: ").append(errorReason); } @@ -336,15 +339,15 @@ public class SdcReceptionHandler extends AbstractReceptionHandler implements INo * Sends the component done status to SDC using the input values. * * @param distributionId the distribution Id - * @param status the distribution status - * @param errorReason the error reason + * @param status the distribution status + * @param errorReason the error reason */ private void sendComponentDoneStatus(final String distributionId, final DistributionStatusEnum status, - final String errorReason) { + final String errorReason) { IDistributionClientResult clientResult; final IComponentDoneStatusMessage message = ComponentDoneStatusMessage.builder() - .consumerId(sdcConfig.getConsumerID()).distributionId(distributionId).distributionStatus(status) - .timestamp(System.currentTimeMillis()).build(); + .consumerId(sdcConfig.getConsumerID()).distributionId(distributionId).distributionStatus(status) + .timestamp(System.currentTimeMillis()).build(); if (errorReason == null) { clientResult = distributionClient.sendComponentDoneStatus(message); } else { @@ -353,7 +356,7 @@ public class SdcReceptionHandler extends AbstractReceptionHandler implements INo final var loggerMessage = new StringBuilder(); loggerMessage.append("component done status to SDC with values - ").append("DistributionId") - .append(distributionId).append(" Status: ").append(status.name()); + .append(distributionId).append(" Status: ").append(status.name()); if (errorReason != null) { loggerMessage.append(" ErrorReason: ").append(errorReason); } @@ -374,4 +377,13 @@ public class SdcReceptionHandler extends AbstractReceptionHandler implements INo sdcReceptionHandlerStatus = newStatus; } } + + private File safelyCreateFile(String prefix) throws IOException { + File file = Files.createTempFile(prefix, ".csar").toFile(); + if (file.setReadable(true, false) + && file.setWritable(true, true)) { + return file; + } + return null; + } } diff --git a/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/util/ReceptionUtil.java b/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/util/ReceptionUtil.java index c26286da..6b0c762a 100644 --- a/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/util/ReceptionUtil.java +++ b/plugins/reception-plugins/src/main/java/org/onap/policy/distribution/reception/util/ReceptionUtil.java @@ -20,9 +20,13 @@ package org.onap.policy.distribution.reception.util; +import java.io.BufferedInputStream; import java.io.IOException; +import java.io.InputStream; import java.io.InvalidClassException; import java.nio.file.Path; +import java.util.Enumeration; +import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.onap.policy.common.utils.coder.CoderException; @@ -44,25 +48,20 @@ public class ReceptionUtil { private static final StandardCoder coder = new StandardCoder(); private static final StandardYamlCoder yamlCoder = new StandardYamlCoder(); - private static final long MAX_FILE_SIZE = 512L * 1024; + private static final long THRESHOLD_SIZE = 512L * 1024; + private static final int THRESHOLD_ENTRIES = 10000; + private static final double THRESHOLD_RATIO = 20; /** * Method to ensure validation of entries in the Zipfile. Attempts to solve path * injection java security issues. * * @param entryName name of the ZipEntry to check - * @param csarPath Absolute path to the csar the ZipEntry is in - * @param entrySize size of the ZipEntry + * @param csarPath Absolute path to the csar the ZipEntry is in * @throws PolicyDecodingException if the file size is too large */ - public static void validateZipEntry(String entryName, String csarPath, long entrySize) - throws PolicyDecodingException { - // - // Check file size - // - if (entrySize > MAX_FILE_SIZE) { - throw new PolicyDecodingException("Zip entry for " + entryName + " is too large " + entrySize); - } + public static void validateZipEntry(String entryName, String csarPath) + throws PolicyDecodingException { // // Now ensure that there is no path injection // @@ -78,19 +77,85 @@ public class ReceptionUtil { /** * Method to decode either a json or yaml file into an object. * - * @param zipFile the zip file - * @param entry the entry to read in the zip file. + * @param zipEntryName the zip file name. + * @param entryData the data from entry to decode. * @return the decoded ToscaServiceTemplate object. * @throws CoderException IOException if the file decoding fails. */ - public static ToscaServiceTemplate decodeFile(ZipFile zipFile, final ZipEntry entry) - throws IOException, CoderException { + public static ToscaServiceTemplate decodeFile(String zipEntryName, InputStream entryData) throws CoderException { ToscaServiceTemplate toscaServiceTemplate = null; - if (entry.getName().endsWith(".json")) { - toscaServiceTemplate = coder.decode(zipFile.getInputStream(entry), ToscaServiceTemplate.class); - } else if (entry.getName().endsWith(".yml")) { - toscaServiceTemplate = yamlCoder.decode(zipFile.getInputStream(entry), ToscaServiceTemplate.class); + if (zipEntryName.endsWith(".json")) { + toscaServiceTemplate = coder.decode(entryData, ToscaServiceTemplate.class); + } else if (zipEntryName.endsWith(".yml")) { + toscaServiceTemplate = yamlCoder.decode(entryData, ToscaServiceTemplate.class); } return toscaServiceTemplate; } + + /** + * Unzip the csar file following the security recommendations from sonar cloud to avoid a zip bomb attack. + * + * @param csarFilename csar file which is a zip file. + * @param unzippedTemplates the templates which should be unzipped. + * @param filter contains the keywords for the entry name. + * @throws PolicyDecodingException in case zip file can't be read + * @throws CoderException in case files can't be decoded to a template + */ + public static void unzip(String csarFilename, Map<String, ToscaServiceTemplate> unzippedTemplates, String... filter) + throws PolicyDecodingException, CoderException { + try (var zipFile = new ZipFile(csarFilename)) { + int totalSizeArchive = 0; + int totalEntryArchive = 0; + + Enumeration<? extends ZipEntry> entries = zipFile.entries(); + + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + totalEntryArchive++; + + if (checkEntryFilter(entry.getName(), filter)) { + validateZipEntry(entry.getName(), csarFilename); + InputStream entryData = new BufferedInputStream(zipFile.getInputStream(entry)); + + int bufferedBytes; + byte[] buffer = new byte[2048]; + int totalSizeEntry = 0; + + boolean isValidThreshold = true; + while ((bufferedBytes = entryData.read(buffer)) > 0 && isValidThreshold) { + totalSizeEntry += bufferedBytes; + totalSizeArchive += bufferedBytes; + + double compressionRatio = Math.floorDiv(totalSizeEntry, entry.getCompressedSize()); + isValidThreshold = compressionRatio <= THRESHOLD_RATIO; + } + + unzippedTemplates.put(entry.getName(), decodeFile(entry.getName(), zipFile.getInputStream(entry))); + } + + if (totalSizeArchive > THRESHOLD_SIZE || totalEntryArchive > THRESHOLD_ENTRIES) { + // the uncompressed data size is too much for the application resource capacity + break; + } + } + } catch (IOException exception) { + throw new PolicyDecodingException("Couldn't read the zipFile", exception); + } + } + + /** + * Check if entry is the one to be unzipped based on the filter. + * + * @param entryName zip file entry name. + * @param filter the list of filter to be looked up on entry names. + * @return true if entry is in filter, false otherwise. + */ + public static boolean checkEntryFilter(String entryName, String... filter) { + for (String f : filter) { + if (entryName.contains(f)) { + return true; + } + } + return false; + } } |