Skip to content

Commit 6a162be

Browse files
author
Po Lu
committed
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.
1 parent 3c2df93 commit 6a162be

File tree

1 file changed

+50
-30
lines changed

1 file changed

+50
-30
lines changed

src/androidvfs.c

Lines changed: 50 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ static char *
458458
android_vfs_canonicalize_name (char *name, size_t *length)
459459
{
460460
size_t nellipsis, i;
461-
char *last_component, *prev_component, *fill, *orig_name;
461+
char *last_component, *prec_component, *fill, *orig_name;
462462
size_t size;
463463

464464
/* Special case described in the last paragraph of the comment
@@ -474,8 +474,8 @@ android_vfs_canonicalize_name (char *name, size_t *length)
474474

475475
nellipsis = 0; /* Number of ellipsis encountered within the current
476476
file name component, or -1. */
477-
prev_component = NULL; /* Pointer to the separator character of
478-
the component immediately before the
477+
prec_component = NULL; /* Pointer to the separator character of the
478+
component immediately preceding the
479479
component currently being written. */
480480
last_component = name; /* Pointer to the separator character of
481481
the component currently being read. */
@@ -502,31 +502,36 @@ android_vfs_canonicalize_name (char *name, size_t *length)
502502
{
503503
/* .. */
504504

505-
if (!prev_component)
506-
goto parent_vnode;
505+
if (!prec_component)
506+
{
507+
/* Return the content of the component, i.e. the text
508+
_after_ this separator. */
509+
i++;
510+
goto parent_vnode;
511+
}
507512

508513
/* Return to the last component. */
509-
fill = prev_component;
514+
fill = prec_component;
510515

511-
/* Restore last_component to prev_component, and
512-
prev_component back to the component before that. */
513-
last_component = prev_component;
516+
/* Restore last_component to prec_component, and
517+
prec_component back to the component before that. */
518+
last_component = prec_component;
514519

515-
if (last_component != name)
516-
prev_component = memrchr (name, '/',
517-
last_component - name - 1);
520+
if (last_component != orig_name)
521+
prec_component = memrchr (orig_name, '/',
522+
last_component - orig_name - 1);
518523
else
519-
prev_component = NULL;
524+
prec_component = NULL;
520525

521-
/* prev_component may now be NULL. If last_component is
522-
the same as NAME, then fill has really been returned
523-
to the beginning of the string, so leave it be. But
524-
if it's something else, then it must be the first
525-
separator character in the string, so set
526-
prev_component to NAME itself. */
526+
/* prec_component may now be NULL. If last_component is
527+
identical to the initial value of NAME, then fill has
528+
really been returned to the beginning of the string, so
529+
leave it be. But if it's something else, then it must
530+
be the first separator character in the string, so set
531+
prec_component to this initial value itself. */
527532

528-
if (!prev_component && last_component != name)
529-
prev_component = name;
533+
if (!prec_component && last_component != orig_name)
534+
prec_component = orig_name;
530535
}
531536
else if (nellipsis == 1)
532537
/* If it's ., return to this component. */
@@ -536,7 +541,7 @@ android_vfs_canonicalize_name (char *name, size_t *length)
536541
/* Record the position of the last directory separator,
537542
so NAME can be overwritten from there onwards if `..'
538543
or `.' are encountered. */
539-
prev_component = last_component;
544+
prec_component = last_component;
540545
last_component = fill;
541546
}
542547

@@ -568,12 +573,12 @@ android_vfs_canonicalize_name (char *name, size_t *length)
568573
{
569574
/* .. */
570575

571-
if (!prev_component)
576+
if (!prec_component)
572577
/* Look up the rest of the vnode in its parent. */
573578
goto parent_vnode;
574579

575580
/* Return to the last component. */
576-
fill = prev_component;
581+
fill = prec_component;
577582
nellipsis = -2;
578583
}
579584
else if (nellipsis == 1)
@@ -684,19 +689,20 @@ android_unix_name (struct android_vnode *vnode, char *name,
684689
input = (struct android_unix_vnode *) vnode;
685690
remainder = android_vfs_canonicalize_name (name, &length);
686691

687-
/* If remainder is set, it's a name relative to the parent
688-
vnode. */
692+
/* If remainder is set, it's a name relative to the parent vnode. */
689693
if (remainder)
690694
goto parent_vnode;
691695

692696
/* Create a new unix vnode. */
693697
vp = xmalloc (sizeof *vp);
694698

695-
/* If name is empty, duplicate the current vnode. */
699+
/* If name is empty, duplicate the current vnode, but reset its file
700+
operation vector to that for Unix vnodes. */
696701

697702
if (length < 1)
698703
{
699704
memcpy (vp, vnode, sizeof *vp);
705+
vp->vnode.ops = &unix_vfs_ops;
700706
vp->name = xstrdup (vp->name);
701707
return &vp->vnode;
702708
}
@@ -748,7 +754,7 @@ android_unix_name (struct android_vnode *vnode, char *name,
748754
vnode = &root_vnode.vnode;
749755
else
750756
{
751-
/* Create a temporary asset vnode within the parent and use it
757+
/* Create a temporary unix vnode within the parent and use it
752758
instead. First, establish the length of vp->name before its
753759
last component. */
754760

@@ -783,7 +789,9 @@ android_unix_name (struct android_vnode *vnode, char *name,
783789
return vnode;
784790
}
785791

786-
return (*vnode->ops->name) (vnode, remainder, strlen (remainder));
792+
/* Virtual directories must be ignored in accessing the root directory
793+
through a Unix subdirectory of the root, as, `/../' */
794+
return android_unix_name (vnode, remainder, strlen (remainder));
787795
}
788796

789797
/* Create a Unix vnode representing the given file NAME. Use this
@@ -6624,6 +6632,7 @@ android_root_name (struct android_vnode *vnode, char *name,
66246632
size_t i;
66256633
Lisp_Object file_name;
66266634
struct android_vnode *vp;
6635+
struct android_unix_vnode *unix_vp;
66276636

66286637
/* Skip any leading separator in NAME. */
66296638

@@ -6706,7 +6715,18 @@ android_root_name (struct android_vnode *vnode, char *name,
67066715
}
67076716
}
67086717

6709-
/* Otherwise, continue searching for a vnode normally. */
6718+
/* Otherwise, continue searching for a vnode normally, but duplicate
6719+
the vnode manually if length is 0, as `android_unix_name' resets
6720+
the vnode operation vector in copies. */
6721+
6722+
if (!length)
6723+
{
6724+
unix_vp = xmalloc (sizeof *unix_vp);
6725+
memcpy (unix_vp, vnode, sizeof *unix_vp);
6726+
unix_vp->name = xstrdup (unix_vp->name);
6727+
return &unix_vp->vnode;
6728+
}
6729+
67106730
return android_unix_name (vnode, name, length);
67116731
}
67126732

0 commit comments

Comments
 (0)