From: Po Lu Date: Tue, 18 Jun 2024 06:41:26 +0000 (+0800) Subject: Correct resolution of non-virtual directory names on Android X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=0b2971668c911e7fad6e8464ed6d13f8e7dfa31e;p=emacs.git Correct resolution of non-virtual directory names on Android * src/androidvfs.c (android_vfs_canonicalize_name): Correct return value in cases of underflowing the directory stack. (android_unix_name): Reset vnode operations vector of copied vnodes to their standard value, and exclude virtual directories from subdirectories of the root directory's parent directory. (android_root_name): Adjust to match. (cherry picked from commit 6a162be6a8f4681d3465fac7573b9f42cfbeaefb) --- diff --git a/src/androidvfs.c b/src/androidvfs.c index d28a74918f6..28a23920533 100644 --- a/src/androidvfs.c +++ b/src/androidvfs.c @@ -458,7 +458,7 @@ static char * android_vfs_canonicalize_name (char *name, size_t *length) { size_t nellipsis, i; - char *last_component, *prev_component, *fill, *orig_name; + char *last_component, *prec_component, *fill, *orig_name; size_t size; /* Special case described in the last paragraph of the comment @@ -474,8 +474,8 @@ android_vfs_canonicalize_name (char *name, size_t *length) nellipsis = 0; /* Number of ellipsis encountered within the current file name component, or -1. */ - prev_component = NULL; /* Pointer to the separator character of - the component immediately before the + prec_component = NULL; /* Pointer to the separator character of the + component immediately preceding the component currently being written. */ last_component = name; /* Pointer to the separator character of the component currently being read. */ @@ -502,31 +502,36 @@ android_vfs_canonicalize_name (char *name, size_t *length) { /* .. */ - if (!prev_component) - goto parent_vnode; + if (!prec_component) + { + /* Return the content of the component, i.e. the text + _after_ this separator. */ + i++; + goto parent_vnode; + } /* Return to the last component. */ - fill = prev_component; + fill = prec_component; - /* Restore last_component to prev_component, and - prev_component back to the component before that. */ - last_component = prev_component; + /* Restore last_component to prec_component, and + prec_component back to the component before that. */ + last_component = prec_component; - if (last_component != name) - prev_component = memrchr (name, '/', - last_component - name - 1); + if (last_component != orig_name) + prec_component = memrchr (orig_name, '/', + last_component - orig_name - 1); else - prev_component = NULL; + prec_component = NULL; - /* prev_component may now be NULL. If last_component is - the same as NAME, then fill has really been returned - to the beginning of the string, so leave it be. But - if it's something else, then it must be the first - separator character in the string, so set - prev_component to NAME itself. */ + /* prec_component may now be NULL. If last_component is + identical to the initial value of NAME, then fill has + really been returned to the beginning of the string, so + leave it be. But if it's something else, then it must + be the first separator character in the string, so set + prec_component to this initial value itself. */ - if (!prev_component && last_component != name) - prev_component = name; + if (!prec_component && last_component != orig_name) + prec_component = orig_name; } else if (nellipsis == 1) /* If it's ., return to this component. */ @@ -536,7 +541,7 @@ android_vfs_canonicalize_name (char *name, size_t *length) /* Record the position of the last directory separator, so NAME can be overwritten from there onwards if `..' or `.' are encountered. */ - prev_component = last_component; + prec_component = last_component; last_component = fill; } @@ -568,12 +573,12 @@ android_vfs_canonicalize_name (char *name, size_t *length) { /* .. */ - if (!prev_component) + if (!prec_component) /* Look up the rest of the vnode in its parent. */ goto parent_vnode; /* Return to the last component. */ - fill = prev_component; + fill = prec_component; nellipsis = -2; } else if (nellipsis == 1) @@ -684,19 +689,20 @@ android_unix_name (struct android_vnode *vnode, char *name, input = (struct android_unix_vnode *) vnode; remainder = android_vfs_canonicalize_name (name, &length); - /* If remainder is set, it's a name relative to the parent - vnode. */ + /* If remainder is set, it's a name relative to the parent vnode. */ if (remainder) goto parent_vnode; /* Create a new unix vnode. */ vp = xmalloc (sizeof *vp); - /* If name is empty, duplicate the current vnode. */ + /* If name is empty, duplicate the current vnode, but reset its file + operation vector to that for Unix vnodes. */ if (length < 1) { memcpy (vp, vnode, sizeof *vp); + vp->vnode.ops = &unix_vfs_ops; vp->name = xstrdup (vp->name); return &vp->vnode; } @@ -748,7 +754,7 @@ android_unix_name (struct android_vnode *vnode, char *name, vnode = &root_vnode.vnode; else { - /* Create a temporary asset vnode within the parent and use it + /* Create a temporary unix vnode within the parent and use it instead. First, establish the length of vp->name before its last component. */ @@ -783,7 +789,9 @@ android_unix_name (struct android_vnode *vnode, char *name, return vnode; } - return (*vnode->ops->name) (vnode, remainder, strlen (remainder)); + /* Virtual directories must be ignored in accessing the root directory + through a Unix subdirectory of the root, as, `/../' */ + return android_unix_name (vnode, remainder, strlen (remainder)); } /* Create a Unix vnode representing the given file NAME. Use this @@ -6624,6 +6632,7 @@ android_root_name (struct android_vnode *vnode, char *name, size_t i; Lisp_Object file_name; struct android_vnode *vp; + struct android_unix_vnode *unix_vp; /* Skip any leading separator in NAME. */ @@ -6706,7 +6715,18 @@ android_root_name (struct android_vnode *vnode, char *name, } } - /* Otherwise, continue searching for a vnode normally. */ + /* Otherwise, continue searching for a vnode normally, but duplicate + the vnode manually if length is 0, as `android_unix_name' resets + the vnode operation vector in copies. */ + + if (!length) + { + unix_vp = xmalloc (sizeof *unix_vp); + memcpy (unix_vp, vnode, sizeof *unix_vp); + unix_vp->name = xstrdup (unix_vp->name); + return &unix_vp->vnode; + } + return android_unix_name (vnode, name, length); }