You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ia...@apache.org on 2014/01/31 22:58:42 UTC

git commit: CB-5960: ios: android: Properly handle parent references in getFile/getDirectory

Updated Branches:
  refs/heads/dev e3d9ac12b -> 4ce92dff1


CB-5960: ios: android: Properly handle parent references in getFile/getDirectory


Project: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/commit/4ce92dff
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/4ce92dff
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/4ce92dff

Branch: refs/heads/dev
Commit: 4ce92dff1b554b0a5d3a5e88bac2cf019f9266ae
Parents: e3d9ac1
Author: Ian Clelland <ic...@chromium.org>
Authored: Fri Jan 31 16:58:05 2014 -0500
Committer: Ian Clelland <ic...@chromium.org>
Committed: Fri Jan 31 16:58:05 2014 -0500

----------------------------------------------------------------------
 src/android/LocalFilesystem.java | 48 ++++++++++++++++++++++++++++++---
 src/ios/CDVLocalFilesystem.m     | 50 ++++++++++++++++++++++++++++++-----
 2 files changed, 88 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/4ce92dff/src/android/LocalFilesystem.java
----------------------------------------------------------------------
diff --git a/src/android/LocalFilesystem.java b/src/android/LocalFilesystem.java
index ebcbaec..762f80b 100644
--- a/src/android/LocalFilesystem.java
+++ b/src/android/LocalFilesystem.java
@@ -10,6 +10,8 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.RandomAccessFile;
 import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.Arrays;
 
 import org.apache.cordova.CordovaInterface;
 import org.json.JSONArray;
@@ -46,15 +48,53 @@ public class LocalFilesystem extends Filesystem {
 		return null;
 	}
 
-	@Override
-	public LocalFilesystemURL URLforFilesystemPath(String path) {
-	    String fullPath = this.fullPathForFilesystemPath(path);
+	protected LocalFilesystemURL URLforFullPath(String fullPath) {
 	    if (fullPath != null) {
+	    	if (fullPath.startsWith("/")) {
+	    		return new LocalFilesystemURL(LocalFilesystemURL.FILESYSTEM_PROTOCOL + "://localhost/"+this.name+fullPath);
+	    	}
 	        return new LocalFilesystemURL(LocalFilesystemURL.FILESYSTEM_PROTOCOL + "://localhost/"+this.name+"/"+fullPath);
 	    }
 	    return null;
+		
+	}
+	
+	@Override
+	public LocalFilesystemURL URLforFilesystemPath(String path) {
+	    return this.URLforFullPath(this.fullPathForFilesystemPath(path));
 	}
 
+	protected String normalizePath(String rawPath) {
+	    // If this is an absolute path, trim the leading "/" and replace it later
+	    boolean isAbsolutePath = rawPath.startsWith("/");
+	    if (isAbsolutePath) {
+	        rawPath = rawPath.substring(1);
+	    }
+	    ArrayList<String> components = new ArrayList<String>(Arrays.asList(rawPath.split("/")));
+	    for (int index = 0; index < components.size(); ++index) {
+	        if (components.get(index).equals("..")) {
+	            components.remove(index);
+	            if (index > 0) {
+	                components.remove(index-1);
+	                --index;
+	            }
+	        }
+	    }
+	    StringBuilder normalizedPath = new StringBuilder();
+	    for(String component: components) {
+	    	normalizedPath.append("/");
+	    	normalizedPath.append(component);
+	    }
+	    if (isAbsolutePath) {
+	    	return normalizedPath.toString();
+	    } else {
+	    	return normalizedPath.toString().substring(1);
+	    }
+
+
+	}
+
+	
 	@Override
     public JSONObject makeEntryForFile(File file) throws JSONException {
     	String path = this.fullPathForFilesystemPath(file.getAbsolutePath());
@@ -116,7 +156,7 @@ public class LocalFilesystem extends Filesystem {
         if (path.startsWith("/")) {
         	requestedURL = URLforFilesystemPath(path);
         } else {
-        	requestedURL = new LocalFilesystemURL(Uri.withAppendedPath(inputURL.URL, path));
+        	requestedURL = URLforFullPath(normalizePath(inputURL.fullPath + "/" + path));
         }
         
         File fp = new File(this.filesystemPathForURL(requestedURL));

http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/4ce92dff/src/ios/CDVLocalFilesystem.m
----------------------------------------------------------------------
diff --git a/src/ios/CDVLocalFilesystem.m b/src/ios/CDVLocalFilesystem.m
index 3e054c8..f16470f 100644
--- a/src/ios/CDVLocalFilesystem.m
+++ b/src/ios/CDVLocalFilesystem.m
@@ -103,15 +103,48 @@
     return path;
 }
 
-- (CDVFilesystemURL *)URLforFilesystemPath:(NSString *)path
+- (CDVFilesystemURL *)URLforFullPath:(NSString *)fullPath
 {
-    NSString *fullPath = [self fullPathForFileSystemPath:path];
     if (fullPath) {
+        if ([fullPath hasPrefix:@"/"])
         return [CDVFilesystemURL fileSystemURLWithString:[NSString stringWithFormat:@"%@://localhost/%@%@", kCDVFilesystemURLPrefix, self.name, fullPath]];
+        return [CDVFilesystemURL fileSystemURLWithString:[NSString stringWithFormat:@"%@://localhost/%@/%@", kCDVFilesystemURLPrefix, self.name, fullPath]];
     }
     return nil;
 }
 
+- (CDVFilesystemURL *)URLforFilesystemPath:(NSString *)path
+{
+    return [self URLforFullPath:[self fullPathForFileSystemPath:path]];
+
+}
+
+- (NSString *)normalizePath:(NSString *)rawPath
+{
+    // If this is an absolute path, the first path component will be '/'. Skip it if that's the case
+    BOOL isAbsolutePath = [rawPath hasPrefix:@"/"];
+    if (isAbsolutePath) {
+        rawPath = [rawPath substringFromIndex:1];
+    }
+    NSMutableArray *components = [NSMutableArray arrayWithArray:[rawPath pathComponents]];
+    for (int index = 0; index < [components count]; ++index) {
+        if ([[components objectAtIndex:index] isEqualToString:@".."]) {
+            [components removeObjectAtIndex:index];
+            if (index > 0) {
+                [components removeObjectAtIndex:index-1];
+                --index;
+            }
+        }
+    }
+    NSString *normalizedPath;
+    if (isAbsolutePath) {
+        return [NSString stringWithFormat:@"/%@", [components componentsJoinedByString:@"/"]];
+    } else {
+        return [components componentsJoinedByString:@"/"];
+    }
+
+
+}
 
 - (CDVPluginResult *)getFileForURL:(CDVFilesystemURL *)baseURI requestedPath:(NSString *)requestedPath options:(NSDictionary *)options
 {
@@ -136,14 +169,19 @@
     if ([requestedPath rangeOfString:@":"].location != NSNotFound) {
         errorCode = ENCODING_ERR;
     } else {
-        CDVFilesystemURL* requestedURL = [CDVFilesystemURL fileSystemURLWithURL:[NSURL URLWithString:[requestedPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] relativeToURL:baseURI.url]]; /* TODO: UGLY - FIX */
-
-        // NSLog(@"reqFullPath = %@", reqFullPath);
+        // Build new fullPath for the requested resource.
+        // We concatenate the two paths together, and then scan the resulting string to remove
+        // parent ("..") references. Any parent references at the beginning of the string are
+        // silently removed.
+        NSString *combinedPath = [baseURI.fullPath stringByAppendingPathComponent:[requestedPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
+        combinedPath = [self normalizePath:combinedPath];
+        CDVFilesystemURL* requestedURL = [self URLforFullPath:combinedPath];
+        
         NSFileManager* fileMgr = [[NSFileManager alloc] init];
         BOOL bIsDir;
         BOOL bExists = [fileMgr fileExistsAtPath:[self filesystemPathForURL:requestedURL] isDirectory:&bIsDir];
         if (bExists && (create == NO) && (bIsDir == !bDirRequest)) {
-            // path exists and is of requested type  - return TYPE_MISMATCH_ERR
+            // path exists and is not of requested type  - return TYPE_MISMATCH_ERR
             errorCode = TYPE_MISMATCH_ERR;
         } else if (!bExists && (create == NO)) {
             // path does not exist and create is false - return NOT_FOUND_ERR