This is an automated email from the ASF dual-hosted git repository.

madhan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/atlas.git


The following commit(s) were added to refs/heads/master by this push:
     new 3415913d2 ATLAS-4622: import fix to handle invalid zip entry
3415913d2 is described below

commit 3415913d252597c24c6b5d19d315375a49e64152
Author: Madhan Neethiraj <[email protected]>
AuthorDate: Wed Jun 15 13:33:55 2022 -0700

    ATLAS-4622: import fix to handle invalid zip entry
---
 .../main/java/org/apache/atlas/AtlasErrorCode.java |  2 +
 .../impexp/ZipSourceWithBackingDirectory.java      | 65 +++++++++++++++++++---
 2 files changed, 59 insertions(+), 8 deletions(-)

diff --git a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java 
b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
index 6ca933ff9..ab35f8724 100644
--- a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
+++ b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
@@ -174,6 +174,8 @@ public enum AtlasErrorCode {
     NOT_VALID_FILE(400, "ATLAS-400-00-09C", "Invalid {0} file"),
     ATTRIBUTE_NAME_ALREADY_EXISTS_IN_PARENT_TYPE(400, "ATLAS-400-00-09D", 
"Invalid attribute name: {0}.{1}. Attribute already exists in parent type: 
{2}"),
     ATTRIBUTE_NAME_ALREADY_EXISTS_IN_ANOTHER_PARENT_TYPE(400, 
"ATLAS-400-00-09E", "Invalid attribute name: {0}.{1}. Attribute already exists 
in another parent type: {2}"),
+    IMPORT_INVALID_ZIP_ENTRY(400, "ATLAS-400-00-09F", "{0}: invalid zip entry. 
Reason: {1}"),
+
     UNAUTHORIZED_ACCESS(403, "ATLAS-403-00-001", "{0} is not authorized to 
perform {1}"),
 
     // All Not found enums go here
diff --git 
a/repository/src/main/java/org/apache/atlas/repository/impexp/ZipSourceWithBackingDirectory.java
 
b/repository/src/main/java/org/apache/atlas/repository/impexp/ZipSourceWithBackingDirectory.java
index 79638009d..e798651f8 100644
--- 
a/repository/src/main/java/org/apache/atlas/repository/impexp/ZipSourceWithBackingDirectory.java
+++ 
b/repository/src/main/java/org/apache/atlas/repository/impexp/ZipSourceWithBackingDirectory.java
@@ -45,11 +45,15 @@ import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
 import static org.apache.atlas.AtlasErrorCode.IMPORT_ATTEMPTING_EMPTY_ZIP;
+import static org.apache.atlas.AtlasErrorCode.IMPORT_INVALID_ZIP_ENTRY;
 
 public class ZipSourceWithBackingDirectory implements EntityImportStream {
     private static final Logger LOG = 
LoggerFactory.getLogger(ZipSourceWithBackingDirectory.class);
     private static final String TEMPORARY_DIRECTORY_PREFIX = 
"atlas-import-temp-";
     private static final String EXT_JSON = ".json";
+    private static final String RELATIVE_PARENT_PATH                 = "..";
+    private static final String RELATIVE_PARENT_PATH_WITH_SEP_PREFIX = 
File.separator + RELATIVE_PARENT_PATH;
+    private static final String RELATIVE_PARENT_PATH_WITH_SEP_SUFFIX = 
RELATIVE_PARENT_PATH + File.separator;
 
     private Path tempDirectory;
 
@@ -174,7 +178,11 @@ public class ZipSourceWithBackingDirectory implements 
EntityImportStream {
 
     @Override
     public void onImportComplete(String guid) {
-        getFileFromTemporaryDirectory(guid + EXT_JSON).delete();
+        try {
+            getFileFromTemporaryDirectory(guid + EXT_JSON).delete();
+        } catch (AtlasBaseException excp) {
+            LOG.error("onImportComplete(guid={}): failed", guid, excp);
+        }
     }
 
     @Override
@@ -205,8 +213,10 @@ public class ZipSourceWithBackingDirectory implements 
EntityImportStream {
     @Override
     public void close() {
         creationOrder.clear();
+
         try {
-            LOG.error("Import: Removing temporary directory: {}", 
tempDirectory.toString());
+            LOG.info("Import: Removing temporary directory: {}", 
tempDirectory.toString());
+
             FileUtils.deleteDirectory(tempDirectory.toFile());
         } catch (IOException e) {
             LOG.error("Import: Error deleting: {}", tempDirectory.toString(), 
e);
@@ -227,9 +237,21 @@ public class ZipSourceWithBackingDirectory implements 
EntityImportStream {
     }
 
     private void setupBackingStore(InputStream inputStream, String 
backingDirectory) throws AtlasBaseException, IOException {
-        initTempDirectory(backingDirectory);
-        unzipToTempDirectory(inputStream);
-        setupIterator();
+        try {
+            initTempDirectory(backingDirectory);
+            unzipToTempDirectory(inputStream);
+            setupIterator();
+        } catch (Exception excp) {
+            try {
+                LOG.info("ZipSourceWithBackingDirectory: setupBackingStore() 
failed. Cleaning up..");
+
+                this.close();
+            } catch (Throwable t) {
+                LOG.warn("ZipSourceWithBackingDirectory cleanup failed", t);
+            }
+
+            throw excp;
+        }
     }
 
     private void initTempDirectory(String backingDirectory) throws 
AtlasBaseException {
@@ -277,14 +299,41 @@ public class ZipSourceWithBackingDirectory implements 
EntityImportStream {
     }
 
     private void writeJsonToFile(String entryName, byte[] jsonPayload) throws 
IOException {
-        File f = getFileFromTemporaryDirectory(entryName);
-        Files.write(f.toPath(), jsonPayload);
+        try {
+            File f = getFileFromTemporaryDirectory(entryName);
+
+            Files.write(f.toPath(), jsonPayload);
+        } catch (AtlasBaseException excp) {
+            LOG.error("writeJsonToFile(entryName={}): failed", entryName, 
excp);
+
+            throw new IOException(excp);
+        }
     }
 
-    private File getFileFromTemporaryDirectory(String entryName) {
+    private File getFileFromTemporaryDirectory(String entryName) throws 
AtlasBaseException {
+        if (hasRelativeParentPath(entryName)) {
+            LOG.error("failed to initialize import: found zipEntry having 
relative parent path '{}'", entryName);
+
+            throw new AtlasBaseException(IMPORT_INVALID_ZIP_ENTRY, entryName, 
"has relative parent path");
+        }
+
         return new File(tempDirectory.toFile(), entryName);
     }
 
+    private boolean hasRelativeParentPath(String path) {
+        final boolean ret;
+
+        if (path == null || !path.contains(RELATIVE_PARENT_PATH)) {
+            ret = false;
+        } else {
+            ret = path.equals(RELATIVE_PARENT_PATH) ||
+                  path.contains(RELATIVE_PARENT_PATH_WITH_SEP_PREFIX) ||
+                  path.contains(RELATIVE_PARENT_PATH_WITH_SEP_SUFFIX);
+        }
+
+        return ret;
+    }
+
     private void setupIterator() {
         try {
             creationOrder = 
getJsonFromEntry(ZipExportFileNames.ATLAS_EXPORT_ORDER_NAME.toString(), 
ArrayList.class);

Reply via email to