diff options
| author | Po Lu | 2024-06-18 14:41:26 +0800 |
|---|---|---|
| committer | Po Lu | 2024-06-18 14:41:26 +0800 |
| commit | 6a162be6a8f4681d3465fac7573b9f42cfbeaefb (patch) | |
| tree | 70c058e2a5fe4001d81342bf7c4b0a44ed96675e /src | |
| parent | 3c2df93e063761ee78b25157c689b6d26210f80b (diff) | |
| download | emacs-6a162be6a8f4681d3465fac7573b9f42cfbeaefb.tar.gz emacs-6a162be6a8f4681d3465fac7573b9f42cfbeaefb.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/androidvfs.c | 80 |
1 files changed, 50 insertions, 30 deletions
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 * | |||
| 458 | android_vfs_canonicalize_name (char *name, size_t *length) | 458 | android_vfs_canonicalize_name (char *name, size_t *length) |
| 459 | { | 459 | { |
| 460 | size_t nellipsis, i; | 460 | size_t nellipsis, i; |
| 461 | char *last_component, *prev_component, *fill, *orig_name; | 461 | char *last_component, *prec_component, *fill, *orig_name; |
| 462 | size_t size; | 462 | size_t size; |
| 463 | 463 | ||
| 464 | /* Special case described in the last paragraph of the comment | 464 | /* Special case described in the last paragraph of the comment |
| @@ -474,8 +474,8 @@ android_vfs_canonicalize_name (char *name, size_t *length) | |||
| 474 | 474 | ||
| 475 | nellipsis = 0; /* Number of ellipsis encountered within the current | 475 | nellipsis = 0; /* Number of ellipsis encountered within the current |
| 476 | file name component, or -1. */ | 476 | file name component, or -1. */ |
| 477 | prev_component = NULL; /* Pointer to the separator character of | 477 | prec_component = NULL; /* Pointer to the separator character of the |
| 478 | the component immediately before the | 478 | component immediately preceding the |
| 479 | component currently being written. */ | 479 | component currently being written. */ |
| 480 | last_component = name; /* Pointer to the separator character of | 480 | last_component = name; /* Pointer to the separator character of |
| 481 | the component currently being read. */ | 481 | the component currently being read. */ |
| @@ -502,31 +502,36 @@ android_vfs_canonicalize_name (char *name, size_t *length) | |||
| 502 | { | 502 | { |
| 503 | /* .. */ | 503 | /* .. */ |
| 504 | 504 | ||
| 505 | if (!prev_component) | 505 | if (!prec_component) |
| 506 | goto parent_vnode; | 506 | { |
| 507 | /* Return the content of the component, i.e. the text | ||
| 508 | _after_ this separator. */ | ||
| 509 | i++; | ||
| 510 | goto parent_vnode; | ||
| 511 | } | ||
| 507 | 512 | ||
| 508 | /* Return to the last component. */ | 513 | /* Return to the last component. */ |
| 509 | fill = prev_component; | 514 | fill = prec_component; |
| 510 | 515 | ||
| 511 | /* Restore last_component to prev_component, and | 516 | /* Restore last_component to prec_component, and |
| 512 | prev_component back to the component before that. */ | 517 | prec_component back to the component before that. */ |
| 513 | last_component = prev_component; | 518 | last_component = prec_component; |
| 514 | 519 | ||
| 515 | if (last_component != name) | 520 | if (last_component != orig_name) |
| 516 | prev_component = memrchr (name, '/', | 521 | prec_component = memrchr (orig_name, '/', |
| 517 | last_component - name - 1); | 522 | last_component - orig_name - 1); |
| 518 | else | 523 | else |
| 519 | prev_component = NULL; | 524 | prec_component = NULL; |
| 520 | 525 | ||
| 521 | /* prev_component may now be NULL. If last_component is | 526 | /* prec_component may now be NULL. If last_component is |
| 522 | the same as NAME, then fill has really been returned | 527 | identical to the initial value of NAME, then fill has |
| 523 | to the beginning of the string, so leave it be. But | 528 | really been returned to the beginning of the string, so |
| 524 | if it's something else, then it must be the first | 529 | leave it be. But if it's something else, then it must |
| 525 | separator character in the string, so set | 530 | be the first separator character in the string, so set |
| 526 | prev_component to NAME itself. */ | 531 | prec_component to this initial value itself. */ |
| 527 | 532 | ||
| 528 | if (!prev_component && last_component != name) | 533 | if (!prec_component && last_component != orig_name) |
| 529 | prev_component = name; | 534 | prec_component = orig_name; |
| 530 | } | 535 | } |
| 531 | else if (nellipsis == 1) | 536 | else if (nellipsis == 1) |
| 532 | /* If it's ., return to this component. */ | 537 | /* If it's ., return to this component. */ |
| @@ -536,7 +541,7 @@ android_vfs_canonicalize_name (char *name, size_t *length) | |||
| 536 | /* Record the position of the last directory separator, | 541 | /* Record the position of the last directory separator, |
| 537 | so NAME can be overwritten from there onwards if `..' | 542 | so NAME can be overwritten from there onwards if `..' |
| 538 | or `.' are encountered. */ | 543 | or `.' are encountered. */ |
| 539 | prev_component = last_component; | 544 | prec_component = last_component; |
| 540 | last_component = fill; | 545 | last_component = fill; |
| 541 | } | 546 | } |
| 542 | 547 | ||
| @@ -568,12 +573,12 @@ android_vfs_canonicalize_name (char *name, size_t *length) | |||
| 568 | { | 573 | { |
| 569 | /* .. */ | 574 | /* .. */ |
| 570 | 575 | ||
| 571 | if (!prev_component) | 576 | if (!prec_component) |
| 572 | /* Look up the rest of the vnode in its parent. */ | 577 | /* Look up the rest of the vnode in its parent. */ |
| 573 | goto parent_vnode; | 578 | goto parent_vnode; |
| 574 | 579 | ||
| 575 | /* Return to the last component. */ | 580 | /* Return to the last component. */ |
| 576 | fill = prev_component; | 581 | fill = prec_component; |
| 577 | nellipsis = -2; | 582 | nellipsis = -2; |
| 578 | } | 583 | } |
| 579 | else if (nellipsis == 1) | 584 | else if (nellipsis == 1) |
| @@ -684,19 +689,20 @@ android_unix_name (struct android_vnode *vnode, char *name, | |||
| 684 | input = (struct android_unix_vnode *) vnode; | 689 | input = (struct android_unix_vnode *) vnode; |
| 685 | remainder = android_vfs_canonicalize_name (name, &length); | 690 | remainder = android_vfs_canonicalize_name (name, &length); |
| 686 | 691 | ||
| 687 | /* If remainder is set, it's a name relative to the parent | 692 | /* If remainder is set, it's a name relative to the parent vnode. */ |
| 688 | vnode. */ | ||
| 689 | if (remainder) | 693 | if (remainder) |
| 690 | goto parent_vnode; | 694 | goto parent_vnode; |
| 691 | 695 | ||
| 692 | /* Create a new unix vnode. */ | 696 | /* Create a new unix vnode. */ |
| 693 | vp = xmalloc (sizeof *vp); | 697 | vp = xmalloc (sizeof *vp); |
| 694 | 698 | ||
| 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. */ | ||
| 696 | 701 | ||
| 697 | if (length < 1) | 702 | if (length < 1) |
| 698 | { | 703 | { |
| 699 | memcpy (vp, vnode, sizeof *vp); | 704 | memcpy (vp, vnode, sizeof *vp); |
| 705 | vp->vnode.ops = &unix_vfs_ops; | ||
| 700 | vp->name = xstrdup (vp->name); | 706 | vp->name = xstrdup (vp->name); |
| 701 | return &vp->vnode; | 707 | return &vp->vnode; |
| 702 | } | 708 | } |
| @@ -748,7 +754,7 @@ android_unix_name (struct android_vnode *vnode, char *name, | |||
| 748 | vnode = &root_vnode.vnode; | 754 | vnode = &root_vnode.vnode; |
| 749 | else | 755 | else |
| 750 | { | 756 | { |
| 751 | /* Create a temporary asset vnode within the parent and use it | 757 | /* Create a temporary unix vnode within the parent and use it |
| 752 | instead. First, establish the length of vp->name before its | 758 | instead. First, establish the length of vp->name before its |
| 753 | last component. */ | 759 | last component. */ |
| 754 | 760 | ||
| @@ -783,7 +789,9 @@ android_unix_name (struct android_vnode *vnode, char *name, | |||
| 783 | return vnode; | 789 | return vnode; |
| 784 | } | 790 | } |
| 785 | 791 | ||
| 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)); | ||
| 787 | } | 795 | } |
| 788 | 796 | ||
| 789 | /* Create a Unix vnode representing the given file NAME. Use this | 797 | /* Create a Unix vnode representing the given file NAME. Use this |
| @@ -6624,6 +6632,7 @@ android_root_name (struct android_vnode *vnode, char *name, | |||
| 6624 | size_t i; | 6632 | size_t i; |
| 6625 | Lisp_Object file_name; | 6633 | Lisp_Object file_name; |
| 6626 | struct android_vnode *vp; | 6634 | struct android_vnode *vp; |
| 6635 | struct android_unix_vnode *unix_vp; | ||
| 6627 | 6636 | ||
| 6628 | /* Skip any leading separator in NAME. */ | 6637 | /* Skip any leading separator in NAME. */ |
| 6629 | 6638 | ||
| @@ -6706,7 +6715,18 @@ android_root_name (struct android_vnode *vnode, char *name, | |||
| 6706 | } | 6715 | } |
| 6707 | } | 6716 | } |
| 6708 | 6717 | ||
| 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 | |||
| 6710 | return android_unix_name (vnode, name, length); | 6730 | return android_unix_name (vnode, name, length); |
| 6711 | } | 6731 | } |
| 6712 | 6732 | ||