harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a...@apache.org
Subject svn commit: r587517 - in /harmony/enhanced/classlib/trunk/modules: archive/src/main/java/java/util/zip/ luni/src/main/java/java/io/ luni/src/main/java/org/apache/harmony/luni/util/ luni/src/test/api/windows/org/apache/harmony/luni/tests/java/io/ portli...
Date Tue, 23 Oct 2007 14:29:18 GMT
Author: ayza
Date: Tue Oct 23 07:29:17 2007
New Revision: 587517

URL: http://svn.apache.org/viewvc?rev=587517&view=rev
Log:
The fix for HARMONY-4794 was applied. With this fix Harmony is be able to create & open
& delete files with non-ASCII symbols in names on Windows. All file names are now converted
to UTF-8 before passing to native functions. Correct handling of UTF-8 names was added to
"hyfile.c".

Modified:
    harmony/enhanced/classlib/trunk/modules/archive/src/main/java/java/util/zip/ZipFile.java
    harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/File.java
    harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/util/Util.java
    harmony/enhanced/classlib/trunk/modules/luni/src/test/api/windows/org/apache/harmony/luni/tests/java/io/WinFileTest.java
    harmony/enhanced/classlib/trunk/modules/portlib/src/main/native/port/windows/hyfile.c

Modified: harmony/enhanced/classlib/trunk/modules/archive/src/main/java/java/util/zip/ZipFile.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/java/util/zip/ZipFile.java?rev=587517&r1=587516&r2=587517&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/archive/src/main/java/java/util/zip/ZipFile.java
(original)
+++ harmony/enhanced/classlib/trunk/modules/archive/src/main/java/java/util/zip/ZipFile.java
Tue Oct 23 07:29:17 2007
@@ -112,7 +112,8 @@
     }
 
     private void openZip() throws IOException {
-        int result = openZipImpl(Util.getBytes(fileName));
+        int result = openZipImpl(Util.getUTF8Bytes(fileName));
+
         if (result != 0) {
             switch (result) {
             case 1:

Modified: harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/File.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/File.java?rev=587517&r1=587516&r2=587517&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/File.java (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/File.java Tue Oct 23
07:29:17 2007
@@ -688,7 +688,7 @@
      * @see #getPath
      */
     public boolean isAbsolute() {
-        return isAbsoluteImpl(Util.getBytes(path));
+        return isAbsoluteImpl(Util.getUTF8Bytes(path));
     }
 
     private native boolean isAbsoluteImpl(byte[] filePath);
@@ -1181,7 +1181,7 @@
         if (properPath != null) {
             return properPath;
         }
-        byte[] pathBytes = Util.getUTF8Bytes(path);
+        byte[] pathBytes = Util.getUTF8Bytes(path);       
         if (isAbsoluteImpl(pathBytes)) {
             return properPath = pathBytes;
         }
@@ -1222,7 +1222,7 @@
 
         }
         result += path;
-        return properPath = Util.getUTF8Bytes(result);        
+        return properPath = Util.getUTF8Bytes(result);               
     }
 
     private static native byte[] properPathImpl(byte[] path);

Modified: harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/util/Util.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/util/Util.java?rev=587517&r1=587516&r2=587517&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/util/Util.java
(original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/util/Util.java
Tue Oct 23 07:29:17 2007
@@ -39,29 +39,33 @@
 		if (encoding != null) {
 			try {
 				"".getBytes(encoding);
-			} catch (java.io.UnsupportedEncodingException e) {
-				encoding = null;
+            } catch (Throwable t) {
+                encoding = null;
 			}
 		}
-		defaultEncoding = encoding;
+        defaultEncoding = encoding;
 	}
 
-	public static byte[] getBytes(String name) {
+    /**
+     * Get bytes from String using default encoding; default encoding can
+     *   be changed via "os.encoding" property
+     * @param name input String
+     * @return byte array
+     */
+    public static byte[] getBytes(String name) {
 		if (defaultEncoding != null) {
 			try {
 				return name.getBytes(defaultEncoding);
 			} catch (java.io.UnsupportedEncodingException e) {
 			}
-		}
-		return name.getBytes();
+		}      
+        return name.getBytes();
 	}
     
     /**
-     * Get bytes from String with specific encoding
+     * Get bytes from String with UTF8 encoding
      * @param name
      *          input String
-     * @param encoding
-     *          specific encoding
      * @return byte array
      */
     public static byte[] getUTF8Bytes(String name) {

Modified: harmony/enhanced/classlib/trunk/modules/luni/src/test/api/windows/org/apache/harmony/luni/tests/java/io/WinFileTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/test/api/windows/org/apache/harmony/luni/tests/java/io/WinFileTest.java?rev=587517&r1=587516&r2=587517&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/test/api/windows/org/apache/harmony/luni/tests/java/io/WinFileTest.java
(original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/test/api/windows/org/apache/harmony/luni/tests/java/io/WinFileTest.java
Tue Oct 23 07:29:17 2007
@@ -18,6 +18,10 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+import tests.support.resource.Support_Resources;
 
 import junit.framework.TestCase;
 
@@ -85,4 +89,41 @@
             dir.deleteOnExit();
         }
     }
+
+
+    /**
+     * Regression test for HARMONY-4794
+     */
+    public void testNonASCIIFileName_4794() throws IOException {
+        final String FILENAME="\u30d5\u30a1\u30a4\u30eb1.txt";
+        final String CONTENT = "A pretty predicament";
+        final String CNTNT_CHARSET = "ISO-8859-1"; 
+
+        File folder = Support_Resources.createTempFolder();
+        File f = new File(folder, FILENAME);
+        FileOutputStream fos = new FileOutputStream(f);
+        FileInputStream fis;
+ 
+        f.createNewFile();
+        f.deleteOnExit();
+        fos.write(CONTENT.getBytes(CNTNT_CHARSET));
+        fos.close();
+
+        f = new File(folder, FILENAME);        
+        assertEquals("Invalid file name", FILENAME, f.getName()); 
+        if (f.exists()) {
+            byte tmp[] = new byte[256];
+            String wasRed;
+            int n;
+
+            fis = new FileInputStream(f);
+            n = fis.read(tmp);
+            fis.close();
+            wasRed = new String(tmp, 0, n, CNTNT_CHARSET);
+            assertEquals("Invalid content was red", CONTENT, wasRed);
+        } else {
+            fail("File does not exist");
+        }
+    }
+
 }

Modified: harmony/enhanced/classlib/trunk/modules/portlib/src/main/native/port/windows/hyfile.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/portlib/src/main/native/port/windows/hyfile.c?rev=587517&r1=587516&r2=587517&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/portlib/src/main/native/port/windows/hyfile.c
(original)
+++ harmony/enhanced/classlib/trunk/modules/portlib/src/main/native/port/windows/hyfile.c
Tue Oct 23 07:29:17 2007
@@ -90,9 +90,11 @@
 {
   DWORD result;
   wchar_t *pathW;
+
   convert_path_to_unicode(portLibrary, path, &pathW);
   result = GetFileAttributesW ((LPCWSTR) pathW);
   portLibrary->mem_free_memory(portLibrary, pathW);
+
   if (result == 0xFFFFFFFF)
     {
       result = GetLastError ();
@@ -206,8 +208,9 @@
   strcat (newPath, "*");
   
   convert_path_to_unicode(portLibrary, newPath, &pathW);
-
   result = FindFirstFileW ((LPCWSTR) pathW, &lpFindFileDataW);
+  portLibrary->mem_free_memory(portLibrary, pathW);
+
   if (result == INVALID_HANDLE_VALUE)
     {
       I_32 error = GetLastError ();
@@ -266,13 +269,17 @@
     HANDLE newHandle;
     I_64 result, tempResult;
     I_32 error;
+    wchar_t *pathW;
 
-    newHandle = CreateFile(path, FILE_READ_ATTRIBUTES,  
+    convert_path_to_unicode(portLibrary, path, &pathW);
+    newHandle = CreateFileW(pathW, FILE_READ_ATTRIBUTES,  
         FILE_SHARE_READ,  
         NULL,  
         OPEN_EXISTING,  
         FILE_FLAG_BACKUP_SEMANTICS,  
         NULL);
+    portLibrary->mem_free_memory(portLibrary, pathW);
+
     if (newHandle == INVALID_HANDLE_VALUE)
     {
         error = GetLastError ();
@@ -321,11 +328,18 @@
     I_64 result;
     I_32 error;
     WIN32_FILE_ATTRIBUTE_DATA myStat;
-    int ret = GetFileAttributesEx(path,GetFileExInfoStandard,&myStat);
+    wchar_t *pathW;
+    int ret;
+    
+    convert_path_to_unicode(portLibrary, path, &pathW);
+    ret = GetFileAttributesExW(pathW,GetFileExInfoStandard,&myStat);
+    portLibrary->mem_free_memory(portLibrary, pathW);    
+
     if(ret == 0) {
         error = GetLastError ();
         return portLibrary->error_set_last_error (portLibrary, error, findError (error));
     }
+
     result = ((I_64) myStat.nFileSizeHigh) << 32;
     result += (I_64) myStat.nFileSizeLow;
     return result;
@@ -333,13 +347,59 @@
 
 #undef CDEV_CURRENT_FUNCTION
 
+#define CDEV_CURRENT_FUNCTION is_device_name
+
+/**
+ * Determines if the given file name is a reserved device name
+  
+ * @param[in] fname file name
+ * @return length of device name if given file name is a device name or
+ *   0 otherwise 
+ */
+int
+is_device_name(const char *fname)
+{
+    const char *reserved[] = {"con", "prn", "aux", "nul", "com", "lpt"};
+    int i, len = strlen(fname);
+    
+    for (i = 0; i < 6; i++) {
+        if (i < 4 && len >= 3 && !_stricmp(fname + len - 3, reserved[i]))
{
+            return 3;
+        } else if (len >= 4 && !_strnicmp(fname + len - 4, reserved[i], 3) &&
+                   isdigit(fname[len - 1])) {
+            return 4;
+        }
+    }
+    return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
 #define CDEV_CURRENT_FUNCTION convert_path_to_unicode
 
+
+// Maximum length of path accepted by unicode versions of
+// WinAPI functions is limited to 32767 characters;
+// each character can take up to three bytes in UTF-8.
+#define ABS_PATH_BUF_LEN 32767*3
+   
+/**
+ * Convert UTF-8 encoded path to UTF-16 so it can be used as an argument to
+ * unicode versions of WinAPI fucntions. This function also converts all
+ * relative paths to absolute ones.
+ *
+ * @param[in] portLibrary The port library
+ * @param[in] path UTF-8 encoded null-terminated path
+ * @param[out] pathW Pointer to wide characters array that contains converted
+ *   path
+ *
+ * @note Sets *pathW to null and returns if path cannot be converted 
+ */
 void
 convert_path_to_unicode(struct HyPortLibrary * portLibrary, const char *path,
 	     wchar_t **pathW)
 {
-    int len = strlen(path);
+    int len;
     int wlen;
     char *canonicalpath;
     int srcArrayCount=0;
@@ -347,25 +407,52 @@
     int slashCount=0; //record how many slashes it met.
     int dotsCount=0; //record how many dots following a separator.
     int *slashStack; //record position of every separator.
+    
+    // Buffer to store absolute path name.
+    char absPath[ABS_PATH_BUF_LEN];
+ 
+    if (!path) {
+        *pathW = (void*) 0;
+        return;
+    }
+
+    // check if given path is a name of device: nul, con, lpt1 and etc.
+    if (len = is_device_name(path)) {
+        wlen = MultiByteToWideChar(CP_UTF8, 0, path, -1, *pathW, 0);
+        *pathW = portLibrary->mem_allocate_memory(portLibrary, wlen*sizeof(wchar_t));
+        MultiByteToWideChar(CP_UTF8, 0, path + strlen(path) - len, -1, *pathW, wlen);
+        return;
+    }
+
+    // calculate an absolute path first
+    if (!GetFullPathNameA(path, ABS_PATH_BUF_LEN, absPath, (void*) 0))
+    {
+        // error occurred
+        *pathW = (void*) 0;
+        return;
+    }
+
+    len = strlen(absPath);
+
     slashStack = portLibrary->mem_allocate_memory(portLibrary, len*sizeof(int));
     canonicalpath = portLibrary->mem_allocate_memory(portLibrary, len+5);
 
     strcpy(canonicalpath,"\\\\?\\");
 
     for(srcArrayCount=0,destArrayCount=4;srcArrayCount<len;srcArrayCount++){
-        // the input path of this method has been parsed to absolute path already.
-        if(path[srcArrayCount]=='.'){
+        // we have an absolute path already.
+        if(absPath[srcArrayCount]=='.'){
             // count the dots following last separator.
-            if(dotsCount>0 || path[srcArrayCount-1]=='\\'){
+            if(dotsCount>0 || absPath[srcArrayCount-1]=='\\'){
                 dotsCount++;
                 continue;
             }
         }
         // deal with the dots when we meet next separator.
-        if(path[srcArrayCount]=='\\'){
+        if(absPath[srcArrayCount]=='\\'){
             if(dotsCount == 1){
-        	dotsCount = 0;
-        	continue;
+                dotsCount = 0;
+                continue;
             }else if (dotsCount > 1){
                 if(slashCount-2<0){
                     slashCount=2;
@@ -385,7 +472,7 @@
             canonicalpath[destArrayCount++]='.';
             dotsCount--;
         }
-        canonicalpath[destArrayCount++]=path[srcArrayCount];
+        canonicalpath[destArrayCount++]=absPath[srcArrayCount];
     }
     while(canonicalpath[destArrayCount-1] == '.'){
         destArrayCount--;
@@ -398,6 +485,7 @@
     portLibrary->mem_free_memory(portLibrary, slashStack);
 }
 
+#undef ABS_PATH_BUF_LEN
 #undef CDEV_CURRENT_FUNCTION
 
 #define CDEV_CURRENT_FUNCTION hyfile_mkdir
@@ -416,6 +504,7 @@
 {
     int returnVar=0;
     wchar_t *pathW;
+
     convert_path_to_unicode(portLibrary, path, &pathW);
     returnVar = CreateDirectoryW (pathW, 0);
     portLibrary->mem_free_memory(portLibrary, pathW);
@@ -450,7 +539,16 @@
 hyfile_move (struct HyPortLibrary * portLibrary, const char *pathExist,
 	     const char *pathNew)
 {
-  if (MoveFile (pathExist, pathNew))
+  wchar_t *pathExistW, *pathNewW;
+  int ret;
+  
+  convert_path_to_unicode(portLibrary, pathExist, &pathExistW);
+  convert_path_to_unicode(portLibrary, pathNew, &pathNewW);
+  ret = MoveFileW (pathExistW, pathNewW);
+  portLibrary->mem_free_memory(portLibrary, pathNewW);
+  portLibrary->mem_free_memory(portLibrary, pathExistW);
+  
+  if (ret)
     {
       return 0;
     }
@@ -483,6 +581,7 @@
   DWORD accessMode, shareMode, createMode, flagsAndAttributes;
   HANDLE aHandle;
   I_32 error;
+  wchar_t *pathW;
 
   Trc_PRT_file_open_Entry (path, flags, mode);
 
@@ -516,14 +615,17 @@
 		flagsAndAttributes |= FILE_FLAG_WRITE_THROUGH;
 	}
 
+  convert_path_to_unicode(portLibrary, path, &pathW);
   aHandle =
-    CreateFile (path, accessMode, shareMode, NULL, createMode,
+    CreateFileW (pathW, accessMode, shareMode, NULL, createMode,
 		flagsAndAttributes, NULL);
+
   if (aHandle == INVALID_HANDLE_VALUE)
     {
       error = GetLastError ();
       portLibrary->error_set_last_error (portLibrary, error,
 					 findError (error));
+      portLibrary->mem_free_memory(portLibrary, pathW); 
       Trc_PRT_file_open_Exit2 (error, findError (error));
       return -1;
     }
@@ -537,13 +639,14 @@
 	}
 
       aHandle =
-	CreateFile (path, accessMode, shareMode, NULL, TRUNCATE_EXISTING,
+	CreateFileW (pathW, accessMode, shareMode, NULL, TRUNCATE_EXISTING,
 		    flagsAndAttributes, NULL);
       if (aHandle == INVALID_HANDLE_VALUE)
-	{
+      {
 	  error = GetLastError ();
 	  portLibrary->error_set_last_error (portLibrary, error,
 					     findError (error));
+      portLibrary->mem_free_memory(portLibrary, pathW); 
 	  Trc_PRT_file_open_Exit3 (error, findError (error));
 	  return -1;
 	}
@@ -554,6 +657,7 @@
       portLibrary->file_seek (portLibrary, (IDATA) aHandle, 0, HySeekEnd);
     }
 
+  portLibrary->mem_free_memory(portLibrary, pathW); 
   Trc_PRT_file_open_Exit (aHandle);
   return ((IDATA) aHandle);
 }
@@ -748,14 +852,21 @@
 I_32 VMCALL
 hyfile_unlink (struct HyPortLibrary * portLibrary, const char *path)
 {
+  wchar_t *pathW;
+  int ret;
+
   /* should be able to delete read-only dirs, so we set the file attribute back to normal
*/
-  if (0 == SetFileAttributes (path, FILE_ATTRIBUTE_NORMAL))
+  convert_path_to_unicode(portLibrary, path, &pathW);
+  if (0 == SetFileAttributesW (pathW, FILE_ATTRIBUTE_NORMAL))
     {
       I_32 error = GetLastError ();
       portLibrary->error_set_last_error (portLibrary, error, findError (error));	/* continue
*/
     }
 
-  if (DeleteFile (path))
+  ret = DeleteFileW (pathW);
+  portLibrary->mem_free_memory(portLibrary, pathW);  
+  
+  if (ret)
     {
       return 0;
     }



Mime
View raw message