aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2023-08-14 13:15:08 +0800
committerPo Lu2023-08-14 13:15:08 +0800
commit9fb00904f959a7e94cf992acb3a96e78a05e719c (patch)
tree9b5d11af74a58b42066f3795da87389de1b4a011 /src
parent3895f882337ade7744cf7964d9bab5d79d4aa059 (diff)
downloademacs-9fb00904f959a7e94cf992acb3a96e78a05e719c.tar.gz
emacs-9fb00904f959a7e94cf992acb3a96e78a05e719c.zip
Improve efficiency of checking for access to authority documents
* java/org/gnu/emacs/EmacsService.java (checkContentUri): Take a string instead of a byte array. Then, use checkCallingUriPermission, in lieu of opening the file. * src/android.c (android_check_content_access): Delete unused function. (android_init_emacs_service): Adjust for changes to checkContentUri's signature. * src/androidvfs.c (android_get_content_name): Return the file name in a new buffer. (android_check_content_access): Adjust correspondingly. (android_authority_name): Verify NAME is a valid JNI string.
Diffstat (limited to 'src')
-rw-r--r--src/android.c37
-rw-r--r--src/androidvfs.c57
2 files changed, 35 insertions, 59 deletions
diff --git a/src/android.c b/src/android.c
index 70779f8ccae..ed304baf0e6 100644
--- a/src/android.c
+++ b/src/android.c
@@ -1107,41 +1107,6 @@ android_get_content_name (const char *filename)
1107 return NULL; 1107 return NULL;
1108} 1108}
1109 1109
1110/* Return whether or not the specified FILENAME is an accessible
1111 content URI. MODE specifies what to check. */
1112
1113static bool
1114android_check_content_access (const char *filename, int mode)
1115{
1116 const char *name;
1117 jobject string;
1118 size_t length;
1119 jboolean rc;
1120
1121 name = android_get_content_name (filename);
1122 length = strlen (name);
1123
1124 string = (*android_java_env)->NewByteArray (android_java_env,
1125 length);
1126 android_exception_check ();
1127
1128 (*android_java_env)->SetByteArrayRegion (android_java_env,
1129 string, 0, length,
1130 (jbyte *) name);
1131 rc = (*android_java_env)->CallBooleanMethod (android_java_env,
1132 emacs_service,
1133 service_class.check_content_uri,
1134 string,
1135 (jboolean) ((mode & R_OK)
1136 != 0),
1137 (jboolean) ((mode & W_OK)
1138 != 0));
1139 android_exception_check_1 (string);
1140 ANDROID_DELETE_LOCAL_REF (string);
1141
1142 return rc;
1143}
1144
1145#endif /* 0 */ 1110#endif /* 0 */
1146 1111
1147/* Return the current user's ``home'' directory, which is actually the 1112/* Return the current user's ``home'' directory, which is actually the
@@ -1549,7 +1514,7 @@ android_init_emacs_service (void)
1549 FIND_METHOD (open_content_uri, "openContentUri", 1514 FIND_METHOD (open_content_uri, "openContentUri",
1550 "([BZZZ)I"); 1515 "([BZZZ)I");
1551 FIND_METHOD (check_content_uri, "checkContentUri", 1516 FIND_METHOD (check_content_uri, "checkContentUri",
1552 "([BZZ)Z"); 1517 "(Ljava/lang/String;ZZ)Z");
1553 FIND_METHOD (query_battery, "queryBattery", "()[J"); 1518 FIND_METHOD (query_battery, "queryBattery", "()[J");
1554 FIND_METHOD (update_extracted_text, "updateExtractedText", 1519 FIND_METHOD (update_extracted_text, "updateExtractedText",
1555 "(Lorg/gnu/emacs/EmacsWindow;" 1520 "(Lorg/gnu/emacs/EmacsWindow;"
diff --git a/src/androidvfs.c b/src/androidvfs.c
index 0385e7348c6..1b82753be3d 100644
--- a/src/androidvfs.c
+++ b/src/androidvfs.c
@@ -2765,14 +2765,13 @@ android_content_initial (char *name, size_t length)
2765/* Return the content URI corresponding to a `/content/by-authority' 2765/* Return the content URI corresponding to a `/content/by-authority'
2766 file name, or NULL if it is invalid for some reason. FILENAME 2766 file name, or NULL if it is invalid for some reason. FILENAME
2767 should be relative to /content/by-authority, with no leading 2767 should be relative to /content/by-authority, with no leading
2768 directory separator character. 2768 directory separator character. */
2769 2769
2770 This function is not reentrant. */ 2770static char *
2771
2772static const char *
2773android_get_content_name (const char *filename) 2771android_get_content_name (const char *filename)
2774{ 2772{
2775 static char buffer[PATH_MAX + 1], *fill; 2773 char *fill, *buffer;
2774 size_t length;
2776 2775
2777 /* Make sure FILENAME isn't obviously invalid: it must contain an 2776 /* Make sure FILENAME isn't obviously invalid: it must contain an
2778 authority name and a file name component. */ 2777 authority name and a file name component. */
@@ -2784,48 +2783,53 @@ android_get_content_name (const char *filename)
2784 return NULL; 2783 return NULL;
2785 } 2784 }
2786 2785
2787 /* FILENAME must also not be a directory. */ 2786 /* FILENAME must also not be a directory. Accessing content
2787 provider directories is not supported by this interface. */
2788 2788
2789 if (filename[strlen (filename)] == '/') 2789 length = strlen (filename);
2790 if (filename[length] == '/')
2790 { 2791 {
2791 errno = ENOTDIR; 2792 errno = ENOTDIR;
2792 return NULL; 2793 return NULL;
2793 } 2794 }
2794 2795
2795 snprintf (buffer, PATH_MAX + 1, "content://%s", filename); 2796 /* Prefix FILENAME with content:// and return the buffer containing
2797 that URI. */
2798
2799 buffer = xmalloc (sizeof "content://" + length);
2800 sprintf (buffer, "content://%s", filename);
2796 return buffer; 2801 return buffer;
2797} 2802}
2798 2803
2799/* Return whether or not the specified URI is an accessible content 2804/* Return whether or not the specified URI is an accessible content
2800 URI. MODE specifies what to check. */ 2805 URI. MODE specifies what to check.
2806
2807 URI must be a string in the JVM's extended UTF-8 format. */
2801 2808
2802static bool 2809static bool
2803android_check_content_access (const char *uri, int mode) 2810android_check_content_access (const char *uri, int mode)
2804{ 2811{
2805 jobject string; 2812 jobject string;
2806 size_t length; 2813 size_t length;
2807 jboolean rc; 2814 jboolean rc, read, write;
2808 2815
2809 length = strlen (uri); 2816 length = strlen (uri);
2810 2817
2811 string = (*android_java_env)->NewByteArray (android_java_env, 2818 string = (*android_java_env)->NewStringUTF (android_java_env, uri);
2812 length);
2813 android_exception_check (); 2819 android_exception_check ();
2814 2820
2815 (*android_java_env)->SetByteArrayRegion (android_java_env, 2821 /* Establish what is being checked. Checking for read access is
2816 string, 0, length, 2822 identical to checking if the file exists. */
2817 (jbyte *) uri); 2823
2824 read = (bool) (mode & R_OK || (mode == F_OK));
2825 write = (bool) (mode & W_OK);
2826
2818 rc = (*android_java_env)->CallBooleanMethod (android_java_env, 2827 rc = (*android_java_env)->CallBooleanMethod (android_java_env,
2819 emacs_service, 2828 emacs_service,
2820 service_class.check_content_uri, 2829 service_class.check_content_uri,
2821 string, 2830 string, read, write);
2822 (jboolean) ((mode & R_OK)
2823 != 0),
2824 (jboolean) ((mode & W_OK)
2825 != 0));
2826 android_exception_check_1 (string); 2831 android_exception_check_1 (string);
2827 ANDROID_DELETE_LOCAL_REF (string); 2832 ANDROID_DELETE_LOCAL_REF (string);
2828
2829 return rc; 2833 return rc;
2830} 2834}
2831 2835
@@ -2889,7 +2893,7 @@ android_authority_name (struct android_vnode *vnode, char *name,
2889 size_t length) 2893 size_t length)
2890{ 2894{
2891 struct android_authority_vnode *vp; 2895 struct android_authority_vnode *vp;
2892 const char *uri_name; 2896 char *uri_name;
2893 2897
2894 if (!android_init_gui) 2898 if (!android_init_gui)
2895 { 2899 {
@@ -2922,6 +2926,12 @@ android_authority_name (struct android_vnode *vnode, char *name,
2922 if (*name == '/') 2926 if (*name == '/')
2923 name++, length -= 1; 2927 name++, length -= 1;
2924 2928
2929 /* NAME must be a valid JNI string, so that it can be encoded
2930 properly. */
2931
2932 if (android_verify_jni_string (name))
2933 goto no_entry;
2934
2925 uri_name = android_get_content_name (name); 2935 uri_name = android_get_content_name (name);
2926 if (!uri_name) 2936 if (!uri_name)
2927 goto error; 2937 goto error;
@@ -2931,11 +2941,12 @@ android_authority_name (struct android_vnode *vnode, char *name,
2931 vp->vnode.ops = &authority_vfs_ops; 2941 vp->vnode.ops = &authority_vfs_ops;
2932 vp->vnode.type = ANDROID_VNODE_CONTENT_AUTHORITY; 2942 vp->vnode.type = ANDROID_VNODE_CONTENT_AUTHORITY;
2933 vp->vnode.flags = 0; 2943 vp->vnode.flags = 0;
2934 vp->uri = xstrdup (uri_name); 2944 vp->uri = uri_name;
2935 return &vp->vnode; 2945 return &vp->vnode;
2936 } 2946 }
2937 2947
2938 /* Content files can't have children. */ 2948 /* Content files can't have children. */
2949 no_entry:
2939 errno = ENOENT; 2950 errno = ENOENT;
2940 error: 2951 error:
2941 return NULL; 2952 return NULL;