aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2023-08-01 21:06:06 +0800
committerPo Lu2023-08-01 21:06:06 +0800
commite41349dd93ffec2b1e383cb4c4dfdb59f6e7edac (patch)
tree0fcd44202d335331c554ebab0730467329729ad0 /src
parentb022398b8f0a03f0e1b3ec8df41a439cdbe5bd19 (diff)
downloademacs-e41349dd93ffec2b1e383cb4c4dfdb59f6e7edac.tar.gz
emacs-e41349dd93ffec2b1e383cb4c4dfdb59f6e7edac.zip
Update Android port
* doc/emacs/android.texi (Android File System): Describe how to access real files named /assets or /contents if so required. * java/org/gnu/emacs/EmacsService.java (validAuthority): * src/android.c (android_init_emacs_service): * src/android.h: New function. * src/androidvfs.c (android_saf_valid_authority_p): New function. Wrap the Java function. (android_saf_root_stat, android_saf_root_access): Don't return success if no authority by vp->authority's name exists. (android_saf_tree_from_name): Check validity of string data before giving it to JNI.
Diffstat (limited to 'src')
-rw-r--r--src/android.c2
-rw-r--r--src/android.h1
-rw-r--r--src/androidvfs.c91
3 files changed, 87 insertions, 7 deletions
diff --git a/src/android.c b/src/android.c
index 2b785319549..c30d7b58979 100644
--- a/src/android.c
+++ b/src/android.c
@@ -1592,6 +1592,8 @@ android_init_emacs_service (void)
1592 "(Ljava/lang/String;Ljava/lang/String;" 1592 "(Ljava/lang/String;Ljava/lang/String;"
1593 "Ljava/lang/String;Ljava/lang/String;" 1593 "Ljava/lang/String;Ljava/lang/String;"
1594 "Ljava/lang/String;)Ljava/lang/String;"); 1594 "Ljava/lang/String;)Ljava/lang/String;");
1595 FIND_METHOD (valid_authority, "validAuthority",
1596 "(Ljava/lang/String;)Z");
1595#undef FIND_METHOD 1597#undef FIND_METHOD
1596} 1598}
1597 1599
diff --git a/src/android.h b/src/android.h
index 8440fb9bc75..945bd649c18 100644
--- a/src/android.h
+++ b/src/android.h
@@ -284,6 +284,7 @@ struct android_emacs_service
284 jmethodID delete_document; 284 jmethodID delete_document;
285 jmethodID rename_document; 285 jmethodID rename_document;
286 jmethodID move_document; 286 jmethodID move_document;
287 jmethodID valid_authority;
287}; 288};
288 289
289extern JNIEnv *android_java_env; 290extern JNIEnv *android_java_env;
diff --git a/src/androidvfs.c b/src/androidvfs.c
index eeef5ea5db0..e3b0b895df3 100644
--- a/src/androidvfs.c
+++ b/src/androidvfs.c
@@ -3249,6 +3249,43 @@ static struct android_saf_root_vdir *all_saf_root_vdirs;
3249static struct android_vnode *android_saf_tree_from_name (char *, const char *, 3249static struct android_vnode *android_saf_tree_from_name (char *, const char *,
3250 const char *); 3250 const char *);
3251 3251
3252/* Forward declaration. */
3253static int android_verify_jni_string (const char *);
3254
3255/* Ascertain and return whether or not AUTHORITY designates a content
3256 provider offering at least one directory tree accessible to
3257 Emacs. */
3258
3259static bool
3260android_saf_valid_authority_p (const char *authority)
3261{
3262 jobject string;
3263 jboolean valid;
3264 jmethodID method;
3265
3266 /* Make certain AUTHORITY can actually be represented as a Java
3267 string. */
3268
3269 if (android_verify_jni_string (authority))
3270 return false;
3271
3272 /* Build a string containing AUTHORITY. */
3273
3274 string = (*android_java_env)->NewStringUTF (android_java_env,
3275 authority);
3276 android_exception_check ();
3277
3278 method = service_class.valid_authority;
3279 valid
3280 = (*android_java_env)->CallNonvirtualBooleanMethod (android_java_env,
3281 emacs_service,
3282 service_class.class,
3283 method, string);
3284 android_exception_check_1 (string);
3285 ANDROID_DELETE_LOCAL_REF (string);
3286 return valid;
3287}
3288
3252static struct android_vnode * 3289static struct android_vnode *
3253android_saf_root_name (struct android_vnode *vnode, char *name, 3290android_saf_root_name (struct android_vnode *vnode, char *name,
3254 size_t length) 3291 size_t length)
@@ -3311,9 +3348,6 @@ android_saf_root_name (struct android_vnode *vnode, char *name,
3311 return android_saf_tree_from_name (component_end, component, 3348 return android_saf_tree_from_name (component_end, component,
3312 vp->authority); 3349 vp->authority);
3313 3350
3314 /* Otherwise, find the first component of NAME and create a vnode
3315 representing it as an authority. */
3316
3317 /* Create the vnode. */ 3351 /* Create the vnode. */
3318 vp = xmalloc (sizeof *vp); 3352 vp = xmalloc (sizeof *vp);
3319 vp->vnode.ops = &saf_root_vfs_ops; 3353 vp->vnode.ops = &saf_root_vfs_ops;
@@ -3414,6 +3448,22 @@ static int
3414android_saf_root_stat (struct android_vnode *vnode, 3448android_saf_root_stat (struct android_vnode *vnode,
3415 struct stat *statb) 3449 struct stat *statb)
3416{ 3450{
3451 struct android_saf_root_vnode *vp;
3452
3453 /* Verify that the authority actually exists and return ENOENT
3454 otherwise, lest `locate-dominating-file' & co call an operation
3455 that doesn't require listing URIs under this authority, such as
3456 access. */
3457
3458 vp = (struct android_saf_root_vnode *) vnode;
3459
3460 if (vp->authority
3461 && !android_saf_valid_authority_p (vp->authority))
3462 {
3463 errno = ENOENT;
3464 return -1;
3465 }
3466
3417 /* Make up some imaginary statistics for this vnode. */ 3467 /* Make up some imaginary statistics for this vnode. */
3418 3468
3419 memset (statb, 0, sizeof *statb); 3469 memset (statb, 0, sizeof *statb);
@@ -3428,6 +3478,8 @@ android_saf_root_stat (struct android_vnode *vnode,
3428static int 3478static int
3429android_saf_root_access (struct android_vnode *vnode, int mode) 3479android_saf_root_access (struct android_vnode *vnode, int mode)
3430{ 3480{
3481 struct android_saf_root_vnode *vp;
3482
3431 /* Validate MODE. */ 3483 /* Validate MODE. */
3432 3484
3433 if (mode != F_OK && !(mode & (W_OK | X_OK | R_OK))) 3485 if (mode != F_OK && !(mode & (W_OK | X_OK | R_OK)))
@@ -3444,6 +3496,20 @@ android_saf_root_access (struct android_vnode *vnode, int mode)
3444 return -1; 3496 return -1;
3445 } 3497 }
3446 3498
3499 /* Verify that the authority actually exists and return ENOENT
3500 otherwise, lest `locate-dominating-file' & co call an operation
3501 that doesn't require listing URIs under this authority, such as
3502 access. */
3503
3504 vp = (struct android_saf_root_vnode *) vnode;
3505
3506 if (vp->authority
3507 && !android_saf_valid_authority_p (vp->authority))
3508 {
3509 errno = ENOENT;
3510 return -1;
3511 }
3512
3447 return 0; 3513 return 0;
3448} 3514}
3449 3515
@@ -5309,9 +5375,9 @@ android_saf_tree_opendir (struct android_vnode *vnode)
5309 AUTHORITY is the name of the content provider authority that is 5375 AUTHORITY is the name of the content provider authority that is
5310 offering TREE. 5376 offering TREE.
5311 5377
5312 Value is NULL if no document tree or provider by those names 5378 Value is NULL and errno is set if no document tree or provider by
5313 exists, or some other error takes place (for example, if TREE and 5379 those names exists, or some other error takes place (for example,
5314 AUTHORITY aren't encoded correctly.) */ 5380 if TREE and AUTHORITY aren't encoded correctly.) */
5315 5381
5316static struct android_vnode * 5382static struct android_vnode *
5317android_saf_tree_from_name (char *name, const char *tree, 5383android_saf_tree_from_name (char *name, const char *tree,
@@ -5323,7 +5389,18 @@ android_saf_tree_from_name (char *name, const char *tree,
5323 const char *uri; 5389 const char *uri;
5324 struct android_vnode *vp; 5390 struct android_vnode *vp;
5325 5391
5326 /* Assume that TREE and NAME are in ``modified UTF-8 format''. */ 5392 /* It's not a given that NAME and TREE are actually in the modified
5393 UTF-8 format used by the JVM to encode strings, and the JVM
5394 aborts when encountering a string that is not. Make sure they
5395 are valid before continuing. */
5396
5397 if (android_verify_jni_string (name)
5398 || android_verify_jni_string (authority))
5399 {
5400 errno = ENOENT;
5401 return NULL;
5402 }
5403
5327 tree_string = (*android_java_env)->NewStringUTF (android_java_env, 5404 tree_string = (*android_java_env)->NewStringUTF (android_java_env,
5328 tree); 5405 tree);
5329 android_exception_check (); 5406 android_exception_check ();