Skip to content

fix(acl): skip a dirent with no Authority kind instead of hiding the page - #30

Merged
opendev9 merged 1 commit into
devfrom
fix/native-dirent-skip-20261023
Oct 23, 2026
Merged

opendev9 merged 1 commit into
devfrom
fix/native-dirent-skip-20261023

Conversation

@opendev9

Copy link
Copy Markdown

Problem

Follow-up to #29, which started sending the real dirent mode as kind to Hub Authority. The guard it added treated an unknown kind as fatal:

if (... || (!S_ISDIR(mode) && !S_ISREG(mode))) {
    g_free(name);
    goto done;            /* aborts the whole 512-entry chunk */
}

filter_chunk() returning -1 makes cf_acl_filter_dirents() return NULL, which hides every child. So one dirent whose mode is neither regular nor directory empties its entire directory page. That mode is reachable: server/pack-dir.c defines and handles S_IFLNK.

Change

  • invalid names (empty, containing /, ., ..) still abort the chunk — that is corrupt input, not a per-child decision, and the existing contract keeps it
  • an entry with no Authority kind is continued: it gets no permission below and stays hidden, exactly like a denied sibling
  • included records the children that produced a checks[] entry, so permissions[i] still maps to the right dirent and the visible list stays aligned
  • an all-skipped chunk returns 0 (empty page) instead of a fail-closed NULL

Verification

  • python3 -m unittest discover -s tests -p 'test_cf_*.py' → 12 tests OK, including 4 new contracts: skip-vs-abort separation, index alignment (p=included, never p=begin), empty chunk, invalid-name abort
  • python3 tests/test_v2_no_managed_library.py → OK
  • C syntax check not run locally (needs the autotools build to generate seafile-object.h); native MariaDB/Hub integration still requires the manual environment, unchanged by this PR.

…page

`filter_chunk()` aborted the whole 512-entry batch when a child was neither a
regular file nor a directory, and `cf_acl_filter_dirents()` turns one aborted
chunk into a NULL listing: a single native symlink emptied its entire
directory page. `server/pack-dir.c` already carries S_IFLNK, so that dirent is
reachable in the data model.

- names that are empty, '/'-bearing, '.' or '..' still abort the chunk: that is
  corrupt input, not a per-child decision
- an entry without a kind is skipped; it gets no permission below and stays
  hidden, exactly like a denied sibling
- `included` keeps the checks[] order, so permissions[i] still maps to the
  child that produced it, and an all-skipped chunk returns an empty page
  successfully instead of a fail-closed NULL

Cheap contracts updated: skip-vs-abort separation, index alignment and the
empty-chunk path. `python3 -m unittest discover -s tests -p 'test_cf_*.py'`
passes (12 tests). Native MariaDB/Hub integration is unchanged and still needs
the manual environment.
@opendev9
opendev9 merged commit 323857e into dev Oct 23, 2026
1 check passed
@opendev9
opendev9 deleted the fix/native-dirent-skip-20261023 branch October 23, 2026 13:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant