1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00

Android: Fixes #6791: Fixed handling of normal paths in filesystem sync (#6792)

This commit is contained in:
javad mnjd 2022-08-31 14:14:32 +04:30 committed by GitHub
parent 6beaaf75bb
commit ff90166b6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 29 deletions

View File

@ -21,11 +21,13 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.regex.Pattern;
@RequiresApi(api = VERSION_CODES.Q)
@ReactModule(name = SafXModule.NAME)
public class SafXModule extends ReactContextBaseJavaModule {
public static final String NAME = "SafX";
public static Pattern trailingSlash = Pattern.compile("[/\\\\]$");
private final DocumentHelper documentHelper;
public SafXModule(ReactApplicationContext reactContext) {
@ -234,12 +236,16 @@ public class SafXModule extends ReactContextBaseJavaModule {
DocumentFile doc = this.documentHelper.goToDocument(uriString, false, true);
WritableMap[] resolvedDocs =
Arrays.stream(doc.listFiles())
.map(
docEntry ->
DocumentHelper.resolveWithDocument(
docEntry, null, uriString + "/" + docEntry.getName()))
.toArray(WritableMap[]::new);
Arrays.stream(doc.listFiles())
.map(
docEntry ->
DocumentHelper.resolveWithDocument(
docEntry,
null,
trailingSlash.matcher(uriString).replaceFirst("")
+ "/"
+ docEntry.getName()))
.toArray(WritableMap[]::new);
WritableArray resolveData = Arguments.fromJavaArgs(resolvedDocs);
promise.resolve(resolveData);
} catch (FileNotFoundException e) {

View File

@ -378,10 +378,37 @@ public class DocumentHelper {
}
public DocumentFile goToDocument(
String unknownUriString, boolean createIfDirectoryNotExist, boolean includeLastSegment)
throws SecurityException, IOException {
String unknownUriStr, boolean createIfDirectoryNotExist, boolean includeLastSegment)
throws SecurityException, IOException, IllegalArgumentException {
String unknownUriString = UriHelper.getUnifiedUri(unknownUriStr);
if (unknownUriString.startsWith(ContentResolver.SCHEME_FILE)) {
return DocumentFile.fromFile(new File(Uri.parse(unknownUriString).getPath()));
Uri uri = Uri.parse(unknownUriString);
if (uri == null) {
throw new IllegalArgumentException("Invalid Uri String");
}
String path =
uri.getPath()
.substring(
0,
includeLastSegment
? uri.getPath().length()
: uri.getPath().length() - uri.getLastPathSegment().length());
if (createIfDirectoryNotExist) {
File targetFile = new File(path);
if (!targetFile.exists()) {
boolean madeFolder = targetFile.mkdirs();
if (!madeFolder) {
throw new IOException("mkdir failed for Uri with `file` scheme");
}
}
}
DocumentFile targetFile = DocumentFile.fromFile(new File(path));
if (!targetFile.exists()) {
throw new FileNotFoundException(
"Cannot find the given document. File does not exist at '" + unknownUriString + "'");
}
return targetFile;
}
String uriString = UriHelper.normalize(unknownUriString);
String baseUri = "";
@ -459,7 +486,7 @@ public class DocumentHelper {
public void transferFile(
String srcUri, String destUri, boolean replaceIfDestExists, boolean copy, Promise promise) {
try {
DocumentFile srcDoc = this.goToDocument(UriHelper.getUnifiedUri(srcUri), false, true);
DocumentFile srcDoc = this.goToDocument(srcUri, false, true);
if (srcDoc.isDirectory()) {
throw new IllegalArgumentException("Cannot move directories");
@ -467,7 +494,7 @@ public class DocumentHelper {
DocumentFile destDoc;
try {
destDoc = this.goToDocument(UriHelper.getUnifiedUri(destUri), false, true);
destDoc = this.goToDocument(destUri, false, true);
if (!replaceIfDestExists) {
throw new IOException("a document with the same name already exists in destination");
}

View File

@ -15,36 +15,42 @@ public class UriHelper {
}
public static String normalize(String uriString) {
// an abnormal uri example:
// content://com.android.externalstorage.documents/tree/1707-3F0B%3Ajoplin/locks/2_2_fa4f9801e9a545a58f1a6c5d3a7cfded.json
// normalized:
// content://com.android.externalstorage.documents/tree/1707-3F0B%3Ajoplin%2Flocks%2F2_2_fa4f9801e9a545a58f1a6c5d3a7cfded.json
if (uriString.startsWith(ContentResolver.SCHEME_CONTENT)) {
// an abnormal uri example:
// content://com.android.externalstorage.documents/tree/1707-3F0B%3Ajoplin/locks/2_2_fa4f9801e9a545a58f1a6c5d3a7cfded.json
// normalized:
// content://com.android.externalstorage.documents/tree/1707-3F0B%3Ajoplin%2Flocks%2F2_2_fa4f9801e9a545a58f1a6c5d3a7cfded.json
// uri parts:
String[] parts = Uri.decode(uriString).split(":");
return parts[0] + ":" + parts[1] + Uri.encode(":" + parts[2]);
// uri parts:
String[] parts = Uri.decode(uriString).split(":");
return parts[0] + ":" + parts[1] + Uri.encode(":" + parts[2]);
}
return uriString;
}
public static String denormalize(String uriString) {
// an normalized uri example:
// content://com.android.externalstorage.documents/tree/1707-3F0B%3Ajoplin%2Flocks%2F2_2_fa4f9801e9a545a58f1a6c5d3a7cfded.json
// denormalized:
// content://com.android.externalstorage.documents/tree/1707-3F0B/Ajoplin/locks/2_2_fa4f9801e9a545a58f1a6c5d3a7cfded.json
if (uriString.startsWith(ContentResolver.SCHEME_CONTENT)) {
// an normalized uri example:
// content://com.android.externalstorage.documents/tree/1707-3F0B%3Ajoplin%2Flocks%2F2_2_fa4f9801e9a545a58f1a6c5d3a7cfded.json
// denormalized:
// content://com.android.externalstorage.documents/tree/1707-3F0B/Ajoplin/locks/2_2_fa4f9801e9a545a58f1a6c5d3a7cfded.json
return Uri.decode(normalize(uriString));
return Uri.decode(normalize(uriString));
}
return uriString;
}
public static String getUnifiedUri(String uriString) throws Exception {
public static String getUnifiedUri(String uriString) throws IllegalArgumentException {
Uri uri = Uri.parse(uriString);
if (uri.getScheme() == null) {
uri = Uri.parse(ContentResolver.SCHEME_FILE+"://"+uriString);
} else if (!(uri.getScheme().equals(ContentResolver.SCHEME_FILE) || uri.getScheme().equals(ContentResolver.SCHEME_CONTENT))) {
throw new Exception("Scheme not supported");
uri = Uri.parse(ContentResolver.SCHEME_FILE + "://" + uriString);
} else if (!(uri.getScheme().equals(ContentResolver.SCHEME_FILE)
|| uri.getScheme().equals(ContentResolver.SCHEME_CONTENT))) {
throw new IllegalArgumentException("Invalid Uri: Scheme not supported");
}
if (uri.getScheme() == null) {
throw new Exception("Invalid Uri: Cannot determine scheme");
throw new IllegalArgumentException("Invalid Uri: Cannot determine scheme");
}
return uri.toString();