[jboss-cvs] JBossAS SVN: r105469 - projects/profileservice/trunk/core/src/main/java/org/jboss/profileservice/repository/artifact.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Jun 1 08:16:45 EDT 2010


Author: emuckenhuber
Date: 2010-06-01 08:16:45 -0400 (Tue, 01 Jun 2010)
New Revision: 105469

Modified:
   projects/profileservice/trunk/core/src/main/java/org/jboss/profileservice/repository/artifact/ExplodedArtifactTransformer.java
Log:
ignore current and reverse tokens.

Modified: projects/profileservice/trunk/core/src/main/java/org/jboss/profileservice/repository/artifact/ExplodedArtifactTransformer.java
===================================================================
--- projects/profileservice/trunk/core/src/main/java/org/jboss/profileservice/repository/artifact/ExplodedArtifactTransformer.java	2010-06-01 08:49:37 UTC (rev 105468)
+++ projects/profileservice/trunk/core/src/main/java/org/jboss/profileservice/repository/artifact/ExplodedArtifactTransformer.java	2010-06-01 12:16:45 UTC (rev 105469)
@@ -26,6 +26,10 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
 import java.util.jar.JarInputStream;
 import java.util.jar.Manifest;
 import java.util.zip.ZipEntry;
@@ -33,7 +37,9 @@
 import org.jboss.profileservice.spi.repository.ArtifactId;
 import org.jboss.profileservice.spi.repository.ArtifactTransformer;
 import org.jboss.util.file.JarUtils;
+import org.jboss.vfs.VFSUtils;
 import org.jboss.vfs.VirtualFile;
+import org.jboss.vfs.util.PathTokenizer;
 
 /**
  * Exploded artifact transformer.
@@ -43,110 +49,137 @@
  */
 public class ExplodedArtifactTransformer implements ArtifactTransformer<ArtifactId>
 {
-
+   
    /** The instance. */
    private static final ExplodedArtifactTransformer INSTANCE = new ExplodedArtifactTransformer();
+
+   /** The buffer size. */
+   static final int BUFFER_SIZE = 4096;
    
+   @SuppressWarnings("unchecked")
    public static <T extends ArtifactId> ArtifactTransformer<T> getInstance()
    {
       return (ArtifactTransformer<T>) INSTANCE;
    }
    
-   /** The buffer size. */
-   static final int BUFFER_SIZE = 4096;
-   
    public void transform(ArtifactId artifactId, InputStream is, VirtualFile target)
          throws IOException
    {
-      unjar(is, target.getPhysicalFile());
+      // The is should be closed by the client
+      final JarInputStream jis = new JarInputStream(is);
+      unjar(jis, target.getPhysicalFile());
    }
 
    /**
-    * Try to unpack an inputStream.
+    * Unjar the input stream.
     * This is a fork of {@link JarUtils#unjar}, but does not close the
     * InputStream itself, as this is done by the remote deploymentTarget.
     * 
-    * @param in the InputStream
-    * @param dest the destination file
+    * @param jis the JarInputStream
+    * @param dest the destination
     * @throws IOException
-    */
-   static void unjar(InputStream in, File dest) throws IOException
+    */   
+   static void unjar(final JarInputStream jis, final File destDir) throws IOException
    {
-      if (!dest.exists())
+      if (!destDir.exists())
       {
-         dest.mkdirs();
+         destDir.mkdirs();
       }
-      if (!dest.isDirectory())
+      if (!destDir.isDirectory())
       {
          throw new IOException("Destination must be a directory.");
       }
-      JarInputStream jin = new JarInputStream(in);
-      byte[] buffer = new byte[BUFFER_SIZE];
-      
-      ZipEntry entry = jin.getNextEntry();
-      while (entry != null)
+      final Set<File> createdDirs = new HashSet<File>();
+      ZipEntry zipEntry = jis.getNextEntry();
+      while (zipEntry != null)
       {
-         String fileName = entry.getName();
-         if (fileName.charAt(fileName.length() - 1) == '/')
+         boolean valid = true;
+         File current = destDir;
+         final String name = getName(zipEntry);
+         final List<String> tokens = PathTokenizer.getTokens(name);
+         final Iterator<String> it = tokens.iterator();
+         while (it.hasNext())
          {
-            fileName = fileName.substring(0, fileName.length() - 1);
+            String token = it.next();
+            if (PathTokenizer.isCurrentToken(token) || PathTokenizer.isReverseToken(token))
+            {
+               // invalid file; skip it!
+               valid = false;
+               break;
+            }
+            current = new File(current, token);
+            if ((it.hasNext() || zipEntry.isDirectory()) && createdDirs.add(current))
+            {
+               current.mkdir();
+            }
          }
-         if (fileName.charAt(0) == '/')
+         if (valid && !zipEntry.isDirectory())
          {
-            fileName = fileName.substring(1);
-         }
-         if (File.separatorChar != '/')
-         {
-            fileName = fileName.replace('/', File.separatorChar);
-         }
-         File file = new File(dest, fileName);
-         if (entry.isDirectory())
-         {
-            // make sure the directory exists
-            file.mkdirs();
-            jin.closeEntry();
-         } 
-         else
-         {
-            // make sure the directory exists
-            File parent = file.getParentFile();
-            if (parent != null && !parent.exists())
+            final FileOutputStream os = new FileOutputStream(current);
+            try
             {
-               parent.mkdirs();
+               int len = 0;
+               final byte[] buffer = new byte[BUFFER_SIZE];
+               while ((len = jis.read(buffer, 0, buffer.length)) != -1)
+               {
+                  os.write(buffer, 0, len);
+               }
+               os.flush();
+               os.close();
+               current.setLastModified(zipEntry.getTime());
             }
-            
-            // dump the file
-            OutputStream out = new FileOutputStream(file);
-            int len = 0;
-            while ((len = jin.read(buffer, 0, buffer.length)) != -1)
+            finally
             {
-               out.write(buffer, 0, len);
+               VFSUtils.safeClose(os);
             }
-            out.flush();
-            out.close();
-            jin.closeEntry();
-            file.setLastModified(entry.getTime());
          }
-         entry = jin.getNextEntry();
+         jis.closeEntry();
+         zipEntry = jis.getNextEntry();
       }
-      /* Explicity write out the META-INF/MANIFEST.MF so that any headers such
-      as the Class-Path are see for the unpackaged jar
-      */
-      Manifest mf = jin.getManifest();
+      /*
+       * Explicity write out the META-INF/MANIFEST.MF so that any headers such
+       * as the Class-Path are see for the unpackaged jar
+       */
+      final Manifest mf = jis.getManifest();
       if (mf != null)
       {
-         File file = new File(dest, "META-INF/MANIFEST.MF");
-         File parent = file.getParentFile();
-         if( parent.exists() == false )
+         final File file = new File(destDir, "META-INF/MANIFEST.MF");
+         final File parent = file.getParentFile();
+         if (parent.exists() == false)
          {
             parent.mkdirs();
          }
-         OutputStream out = new FileOutputStream(file);
-         mf.write(out);
-         out.flush();
-         out.close();
+         final OutputStream os = new FileOutputStream(file);
+         try
+         {
+            mf.write(os);
+            os.flush();
+            os.close();
+         }
+         finally
+         {
+            VFSUtils.safeClose(os);
+         }
       }
    }
+
+   static String getName(ZipEntry entry)
+   {
+      String fileName = entry.getName();
+      if (fileName.charAt(fileName.length() - 1) == '/')
+      {
+         fileName = fileName.substring(0, fileName.length() - 1);
+      }
+      if (fileName.charAt(0) == '/')
+      {
+         fileName = fileName.substring(1);
+      }
+      if (File.separatorChar != '/')
+      {
+         fileName = fileName.replace('/', File.separatorChar);
+      }
+      return fileName;
+   }
    
 }
 




More information about the jboss-cvs-commits mailing list