aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2023-07-27 21:59:58 +0800
committerPo Lu2023-07-27 21:59:58 +0800
commitde0e0939f01a747b8201e06bda5cd50dfa95187f (patch)
tree20e23c8b0539169ef9f88a561165e7ae90eecc79
parent4e754817b56c80b1a8c9cf4a9ae811d8217347a4 (diff)
downloademacs-de0e0939f01a747b8201e06bda5cd50dfa95187f.tar.gz
emacs-de0e0939f01a747b8201e06bda5cd50dfa95187f.zip
Update Android port
* doc/emacs/android.texi (Android Document Providers): Improve wording of paragraph clarifying limits on subprocesses. * java/org/gnu/emacs/EmacsService.java (getDocumentTrees): Use Java standard US-ASCII coding standard instead of the undocumented ``ASCII'' alias. (decodeFileName): Remove unused function. (documentIdFromName): * src/android.c (android_init_emacs_service): Take a String for NAME instead of a byte array. * src/androidvfs.c (android_verify_jni_string): New function. (android_document_id_from_name): Verify that STRING is a valid Modified UTF-8 string.
-rw-r--r--doc/emacs/android.texi11
-rw-r--r--java/org/gnu/emacs/EmacsService.java34
-rw-r--r--src/android.c3
-rw-r--r--src/androidvfs.c75
4 files changed, 85 insertions, 38 deletions
diff --git a/doc/emacs/android.texi b/doc/emacs/android.texi
index 1f32fdfc1d2..b86c71cea49 100644
--- a/doc/emacs/android.texi
+++ b/doc/emacs/android.texi
@@ -298,11 +298,12 @@ subsequently made available within a new directory named
298a unique identifier assigned to the directory by the document 298a unique identifier assigned to the directory by the document
299provider. 299provider.
300 300
301 Because these directories do not exist within the Unix file-system, 301 The same limitations applied to the @file{/assets} directory
302sub-processes cannot be created within them, just as with the 302(@pxref{Android File System}) are applied when creating sub-processes
303@file{/assets} directory (@pxref{Android File System}.) In addition, 303within those directories, because they do not exist within the Unix
304although Emacs can normally write and create files inside these 304file-system. In addition, although Emacs can normally write and
305directories, it cannot create symlinks or hard links. 305create files inside these directories, it cannot create symlinks or
306hard links.
306 307
307@c TODO: fix this! 308@c TODO: fix this!
308 Since document providers are allowed to perform expensive network 309 Since document providers are allowed to perform expensive network
diff --git a/java/org/gnu/emacs/EmacsService.java b/java/org/gnu/emacs/EmacsService.java
index 6059439551f..bc62e050345 100644
--- a/java/org/gnu/emacs/EmacsService.java
+++ b/java/org/gnu/emacs/EmacsService.java
@@ -1282,7 +1282,7 @@ public final class EmacsService extends Service
1282 1282
1283 try 1283 try
1284 { 1284 {
1285 providerName = new String (provider, "ASCII"); 1285 providerName = new String (provider, "US-ASCII");
1286 } 1286 }
1287 catch (UnsupportedEncodingException exception) 1287 catch (UnsupportedEncodingException exception)
1288 { 1288 {
@@ -1306,24 +1306,6 @@ public final class EmacsService extends Service
1306 return treeList.toArray (new String[0]); 1306 return treeList.toArray (new String[0]);
1307 } 1307 }
1308 1308
1309 /* Decode the specified STRING into a String object using the UTF-8
1310 format. If an exception is thrown, return null. */
1311
1312 private String
1313 decodeFileName (byte[] string)
1314 {
1315 try
1316 {
1317 return new String (string, "UTF-8");
1318 }
1319 catch (Exception e) /* UnsupportedEncodingException, etc. */
1320 {
1321 ;;
1322 }
1323
1324 return null;
1325 }
1326
1327 /* Find the document ID of the file within TREE_URI designated by 1309 /* Find the document ID of the file within TREE_URI designated by
1328 NAME. 1310 NAME.
1329 1311
@@ -1342,11 +1324,10 @@ public final class EmacsService extends Service
1342 If the designated file can't be located, return -1. */ 1324 If the designated file can't be located, return -1. */
1343 1325
1344 private int 1326 private int
1345 documentIdFromName (String tree_uri, byte name[], 1327 documentIdFromName (String tree_uri, String name, String[] id_return)
1346 String[] id_return)
1347 { 1328 {
1348 Uri uri, treeUri; 1329 Uri uri, treeUri;
1349 String nameString, id, type; 1330 String id, type;
1350 String[] components, projection; 1331 String[] components, projection;
1351 Cursor cursor; 1332 Cursor cursor;
1352 int column; 1333 int column;
@@ -1360,11 +1341,8 @@ public final class EmacsService extends Service
1360 /* Parse the URI identifying the tree first. */ 1341 /* Parse the URI identifying the tree first. */
1361 uri = Uri.parse (tree_uri); 1342 uri = Uri.parse (tree_uri);
1362 1343
1363 /* Next, decode NAME. */
1364 nameString = decodeFileName (name);
1365
1366 /* Now, split NAME into its individual components. */ 1344 /* Now, split NAME into its individual components. */
1367 components = nameString.split ("/"); 1345 components = name.split ("/");
1368 1346
1369 /* Set id and type to the value at the root of the tree. */ 1347 /* Set id and type to the value at the root of the tree. */
1370 type = id = null; 1348 type = id = null;
@@ -1462,7 +1440,7 @@ public final class EmacsService extends Service
1462 1440
1463 try 1441 try
1464 { 1442 {
1465 nameString = cursor.getString (column); 1443 name = cursor.getString (column);
1466 } 1444 }
1467 catch (Exception exception) 1445 catch (Exception exception)
1468 { 1446 {
@@ -1473,7 +1451,7 @@ public final class EmacsService extends Service
1473 /* Break out of the loop only once a matching component is 1451 /* Break out of the loop only once a matching component is
1474 found. */ 1452 found. */
1475 1453
1476 if (nameString.equals (component)) 1454 if (name.equals (component))
1477 break; 1455 break;
1478 } 1456 }
1479 1457
diff --git a/src/android.c b/src/android.c
index d8b264a8491..098fa6c383d 100644
--- a/src/android.c
+++ b/src/android.c
@@ -1556,7 +1556,8 @@ android_init_emacs_service (void)
1556 FIND_METHOD (get_document_trees, "getDocumentTrees", 1556 FIND_METHOD (get_document_trees, "getDocumentTrees",
1557 "([B)[Ljava/lang/String;"); 1557 "([B)[Ljava/lang/String;");
1558 FIND_METHOD (document_id_from_name, "documentIdFromName", 1558 FIND_METHOD (document_id_from_name, "documentIdFromName",
1559 "(Ljava/lang/String;[B[Ljava/lang/String;)I"); 1559 "(Ljava/lang/String;Ljava/lang/String;"
1560 "[Ljava/lang/String;)I");
1560 FIND_METHOD (get_tree_uri, "getTreeUri", 1561 FIND_METHOD (get_tree_uri, "getTreeUri",
1561 "(Ljava/lang/String;Ljava/lang/String;)" 1562 "(Ljava/lang/String;Ljava/lang/String;)"
1562 "Ljava/lang/String;"); 1563 "Ljava/lang/String;");
diff --git a/src/androidvfs.c b/src/androidvfs.c
index bab3977ed5a..c174c35f02b 100644
--- a/src/androidvfs.c
+++ b/src/androidvfs.c
@@ -3936,6 +3936,66 @@ static struct android_vops saf_new_vfs_ops;
3936/* Chain of all open SAF directory streams. */ 3936/* Chain of all open SAF directory streams. */
3937static struct android_saf_tree_vdir *all_saf_tree_vdirs; 3937static struct android_saf_tree_vdir *all_saf_tree_vdirs;
3938 3938
3939/* Verify that the specified NULL-terminated STRING is a valid JNI
3940 ``UTF-8'' string. Return 0 if so, 1 otherwise.
3941
3942 The native coding system used by the JVM to store strings derives
3943 from UTF-8, but deviates from it in two aspects in an attempt to
3944 better represent the UCS-16 based Java String format, and to let
3945 strings contain NULL characters while remaining valid C strings:
3946 NULL bytes are encoded as two-byte sequences, and Unicode surrogate
3947 pairs encoded as two-byte sequences are prefered to four-byte
3948 sequences when encoding characters above the BMP. */
3949
3950static int
3951android_verify_jni_string (const char *name)
3952{
3953 const unsigned char *chars;
3954
3955 chars = (unsigned char *) name;
3956 while (*chars)
3957 {
3958 /* Switch on the high 4 bits. */
3959
3960 switch (*chars++ >> 4)
3961 {
3962 case 0 ... 7:
3963 /* The 8th bit is clean, so this is a regular C
3964 character. */
3965 break;
3966
3967 case 8 ... 0xb:
3968 /* Invalid starting byte! */
3969 return 1;
3970
3971 case 0xf:
3972 /* The start of a four byte sequence. These aren't allowed
3973 in Java. */
3974 return 1;
3975
3976 case 0xe:
3977 /* The start of a three byte sequence. Verify that its
3978 continued. */
3979
3980 if ((*chars++ & 0xc0) != 0x80)
3981 return 1;
3982
3983 FALLTHROUGH;
3984
3985 case 0xc ... 0xd:
3986 /* The start of a two byte sequence. Verify that the
3987 next byte exists and has its high bit set. */
3988
3989 if ((*chars++ & 0xc0) != 0x80)
3990 return 1;
3991
3992 break;
3993 }
3994 }
3995
3996 return 0;
3997}
3998
3939/* Find the document ID of the file within TREE_URI designated by 3999/* Find the document ID of the file within TREE_URI designated by
3940 NAME. 4000 NAME.
3941 4001
@@ -3943,6 +4003,9 @@ static struct android_saf_tree_vdir *all_saf_tree_vdirs;
3943 individual files. Each constituent component prior to the last 4003 individual files. Each constituent component prior to the last
3944 must name a directory file within TREE_URI. 4004 must name a directory file within TREE_URI.
3945 4005
4006 If NAME is not correct for the Java ``modified UTF-8'' coding
4007 system, return -1.
4008
3946 Upon success, return 0 or 1 (contingent upon whether or not the 4009 Upon success, return 0 or 1 (contingent upon whether or not the
3947 last component within NAME is a directory) and place the document 4010 last component within NAME is a directory) and place the document
3948 ID of the named file in ID. 4011 ID of the named file in ID.
@@ -3965,6 +4028,12 @@ android_document_id_from_name (const char *tree_uri, char *name,
3965 jmethodID method; 4028 jmethodID method;
3966 const char *doc_id; 4029 const char *doc_id;
3967 4030
4031 /* Verify the format of NAME. Don't allow creating files that
4032 contain characters that can't be encoded in Java. */
4033
4034 if (android_verify_jni_string (name))
4035 return -1;
4036
3968 /* First, create the array that will hold the result. */ 4037 /* First, create the array that will hold the result. */
3969 result = (*android_java_env)->NewObjectArray (android_java_env, 1, 4038 result = (*android_java_env)->NewObjectArray (android_java_env, 1,
3970 java_string_class, 4039 java_string_class,
@@ -3972,11 +4041,9 @@ android_document_id_from_name (const char *tree_uri, char *name,
3972 android_exception_check (); 4041 android_exception_check ();
3973 4042
3974 /* Next, create the string for the tree URI and name. */ 4043 /* Next, create the string for the tree URI and name. */
3975 length = strlen (name); 4044 java_name = (*android_java_env)->NewStringUTF (android_java_env,
3976 java_name = (*android_java_env)->NewByteArray (android_java_env, length); 4045 name);
3977 android_exception_check_1 (result); 4046 android_exception_check_1 (result);
3978 (*android_java_env)->SetByteArrayRegion (android_java_env, java_name,
3979 0, length, (jbyte *) name);
3980 uri = (*android_java_env)->NewStringUTF (android_java_env, tree_uri); 4047 uri = (*android_java_env)->NewStringUTF (android_java_env, tree_uri);
3981 android_exception_check_2 (result, java_name); 4048 android_exception_check_2 (result, java_name);
3982 4049