Commit graph

50 commits

Author SHA1 Message Date
CismonX
29338ca02b
backend_firefox: purge dangling refs on delete
When a bookmark is deleted, if there are no other bookmarks
referencing the corresponding `moz_place` entry, tag and keyword
references to that entry are considered "dangling" references,
and shall be automatically removed.

Also reverts commit b5fa6960ef,
since the NULL title check is no longer necessary.
2025-06-06 22:46:44 +08:00
CismonX
b5fa6960ef
backend_firefox: hide dangling keywords
When a bookmark associated with a keyword is deleted,
there may still be dangling references (e.g., tags) to the
corresponding `moz_places` entry.

By filtering out NULL titles, `bookmark_lookup()` and
`bookmark_list()` now only give keywords associated with
valid bookmarks.
2025-06-05 08:27:59 +08:00
CismonX
5a28b069c4
fs_ops: fix file size opened with O_CREAT|O_TRUNC
Also make sure that new regular files always have a size of zero.
2025-04-29 14:48:39 +08:00
CismonX
83f201435f
backend_firefox: add keyword xattr
This allows users to quickly discover which keyword is
associated with a given bookmark.

Updating keywords via xattr is not implemented,
since it can be done trivially using existing API.
2025-04-29 12:46:29 +08:00
CismonX
0e20604c73
backend_firefox: fix stmt id for keyword delete 2025-04-28 20:04:40 +08:00
CismonX
763bba9444
backend_firefox: fix bookmark_check()
Regression in commit 85b02f6c2b.
2025-04-03 10:23:54 +08:00
CismonX
63d8b8e213
backend_firefox: fix sqlite version compatibility
In commit 348f13df02, we replaced
`length(url)` with `octet_length(url)`.
However, `octet_length` was added in SQLite 3.43, while we claim to
support SQLite 3.35 and later.

Stable GNU/Linux distros like Debian may still be using pre-3.43
releases of SQLite, so don't bump that version too soon.
Instead, use `length(CAST(url AS BLOB))`, which is a bit less
efficient than `octet_length(url)`, but O(1) nonetheless.
2025-03-29 16:14:10 +08:00
CismonX
bdfa812d79
backend: respect the BOOKMARK_DELETE_DIR flag
Following commit 2e3685f217,
make sure all backends check this flag and return correct error codes.

Normally this is not mandatory, since the kernel looks up
the directory entry to be removed, and fails if the system call
is inappropriate (e.g., calling rmdir() on a regular file).
This happens before FUSE_UNLINK or FUSE_RMDIR is sent to the server.

However, when not in exclusive mode, there is a short window that
TOCTOU problem may occur, which may lead to undesired behavior
(e.g., deletion of a non-empty directory) or even the corruption of
bookmark storage if not properly checked.

Also explain this flag in the user manual.
2025-03-27 12:36:27 +08:00
CismonX
2e3685f217
backend_firefox: fix directory deletion
Also reverts commit fef7b4d3a8.

The DELETE_DIR flag is in fact useful, but bookmark_delete()
incorrectly checked CREATE_DIR instead.
2025-03-26 19:03:00 +08:00
CismonX
3422d68193
backend: allow bad system time in readonly mode
In readonly mode, we're not using the current time as timestamp,
thus a bad system time won't hurt.

Also in Chromium backend, use zero timestamp for the bookmark root
dir, to accomodate this change (no one cares about it anyway).
2025-03-23 14:56:16 +08:00
CismonX
750c16077c
backend: prevent timestamp overflow
When updating timestamps, make sure that the corresponding
microsecond value fits in a single signed 64-bit integer,
so that it won't result in an integer overflow, which is UB.

Also forbid timestamps before the Unix epoch, since working with
negative time_t is problematic.

This check does not apply to current timestamp, however,
add a check on backend startup to ensure sane system time.

There's no need to validate `tv_nsec`, since the kernel already
does that for us.
2025-03-20 12:46:11 +08:00
CismonX
e0d2aa2058
backend: refactor bookmark_set() for timestamps
Do not expose UTIME_OMIT to backends, but instead specify
which timestamps to update with flags.

This allows us to further refactor backend code, especially
the Chromium backend.
2025-03-20 12:14:59 +08:00
CismonX
00f40beec7
xstd: add helper function for getting current time
Also, don't bother with failed clock_gettime() calls.
2025-03-19 21:26:27 +08:00
CismonX
bd343ddf4b
backend_firefox: fix integer parsing 2025-03-12 17:22:54 +08:00
CismonX
0a4ff8770e
backend_firefox: misc refactor
- Follow the "best practice" in the SQLite manual, where calls to
  sqlite3_column_bytes() should come after sqlite3_column_text().
  This change does not affect the values returned.
- Other misc updates.
2025-03-11 16:22:29 +08:00
CismonX
48b1d8c98d
backend_firefox: tombstone for deleted bookmarks
If a bookmark is assigned SYNC_STATUS_NORMAL (value 2),
a "tombstone" has to be inserted upon deletion,
so that the browser could purge it from remote.
2025-03-10 14:40:26 +08:00
CismonX
217e185496
backend_firefox: temp ts buffer for usecs_now() 2025-03-09 16:27:09 +08:00
CismonX
85b02f6c2b
backend_firefox, fs_ops: store hashcode in entry
Trade a bit of memory for hashmap rehash/remove efficiency.
2025-03-09 15:44:29 +08:00
CismonX
3e6bcb8b4f
backend_firefox: set bookmark initial sync status
New bookmarks should be assigned SYNC_STATUS_NEW (value 1).
2025-03-09 14:21:13 +08:00
CismonX
c2a91d6420
hashmap: refactor interface
- `hashmap_insert()` no longer takes key as argument, and
  takes the pointer to be associated with the entry as argument.
- Rename `hashmap_entry_delete` -> `hashmap_delete`.
- Make `user_data` the first argument for `hashmap_walk_func`.
- Other misc renames.
2025-03-06 06:40:28 +08:00
CismonX
8cbd5846d9
chore: tidy up 2025-03-01 23:40:34 +08:00
CismonX
6f11f51171
backend_firefox: rename msecs -> usecs
For microseconds, "usecs" is the correct abbreviation,
while "msecs" should be used for milliseconds.
2025-03-01 00:52:18 +08:00
CismonX
f952a35ddc
backend: misc refactor
- Following commit d01554400c, rename `attr_key_*` to `xattr_name_*`.
- Other misc changes.
2025-02-28 10:05:25 +08:00
CismonX
cd648f9ef0
backend_firefox: separator-aware
There's a special kind of bookmark in Firefox known as "separator",
which appears as vertical or horizontal bars in the browser.

BookmarkFS currently does not support managing separators, but
the backend should be aware of their existence, and must not break
when one appears.

A separator always has a NULL `title` and `fk` in `moz_bookmarks`,
so it doesn't break `bookmark_list()` and `bookmark_lookup()`,
but breaks `bookmark_check()` since it could be mistaken for a
bookmark or bookmark folder with NULL title.

Fix by checking the bookmark type in `bookmark_check_cb()`.
2025-02-28 00:07:24 +08:00
CismonX
348f13df02
backend_firefox: improve length(url) performace
The SQLite builtin function `length()` calculates the number of
Unicode code points of the given argument, while `octet_length()`
calculates the number of bytes.

The two functions should produce the same result for a URL since it's
always ASCII-only, however, with `octet_length()` the length can be
directly fetched from metadata without actually reading the URL text,
thereby improving performance.
2025-02-27 14:26:24 +08:00
CismonX
0fd2cbbc9d
backend_firefox: no db_check() in sandbox mode
Following commit 35d4a93a41, now only perform `PRAGMA quick_check`
in non-sandbox mode before querying data on the database.

Although in practice SQLite does well in terms of memory safety,
most likely way better than BookmarkFS itself, we consider
sandboxing a stronger security guarantee than `PRAGMA quick_check`.
2025-02-26 14:06:18 +08:00
CismonX
d01554400c
backend: rename ATTR_KEY_* -> BM_XATTR_* 2025-02-26 13:56:18 +08:00
CismonX
bd90602d4a
xattr: misc refactor
- Check for XATTR_CREATE in setxattr.
- Rename bookmark_attrs -> xattr_names.
- Other misc changes.
2025-02-19 11:34:03 +08:00
CismonX
9afdfc45d7
backend: rename bookmark_check args
- Rename `id` -> `parent_id`, since the function works on
  the parent directory.
2025-02-13 17:48:07 +08:00
CismonX
52b3707d2b
backend: rename bookmark_fsck -> bookmark_check
Some relevant names are also renamed.
2025-02-12 20:47:10 +08:00
CismonX
3375674973
backend: ignore val_len when updating timestamps 2025-02-12 12:36:30 +08:00
CismonX
e199a1203a
backend: fix includes
Fix a regression in commit d1dac54b72 where sys/stat.h is no longer
included in backend_firefox.c and backend_chromium.c.

It has to be explicitly included for the UTIME_xxx macros.
2025-02-10 19:55:43 +08:00
CismonX
cd3d6a6232
backend_firefox: improve mkfs
Switch to schema version 74, so that it is compatible with
browsers (e.g., GNU IceCat) which are still based on
Firefox 115 ESR (now end-of-life), as well as saving us
a bit more space since there are fewer tables to be created.
2025-02-10 18:40:00 +08:00
CismonX
4f8b15fd80
backend_firefox: improve bookmark storage init
- Check schema version when initializing database.
- Minor refactor for db_check().
2025-02-09 23:49:21 +08:00
CismonX
d1dac54b72
chore: tidy up includes 2025-02-08 18:56:45 +08:00
CismonX
d0aa74b212
backend: rename object_free -> cookie_free 2025-02-03 18:15:52 +08:00
CismonX
1d1ff58aa4
ioctl: move type definitions to common.h 2025-02-02 21:35:12 +08:00
CismonX
88e38bd38e
backend: update cookie even on callback failure
No need to check status and always update cookie after
invoking callback for bookmark_list() and bookmark_fsck().
2025-02-01 00:21:02 +08:00
CismonX
78b80be2e5
backend: rename struct bookmarkfs_bookmark_entry
Rename field `next` -> `off`.
2025-01-31 20:31:52 +08:00
CismonX
3ed11f53e5
backend: fix xattr bookmark title check
Do not check if the bookmark title is a valid filename,
as we said in the user manual.

However, we should ensure that the string does not contain
NUL characters, since we assume that a valid bookmark storage
should not contain bookmarks with such names.
2025-01-26 19:35:03 +08:00
CismonX
996ca0e042
backend_firefox: fix and refactor mkfs
- Make sure all tables and indices are created for the database,
  even the ones that are not used by BookmarkFS.
- Maintain the schema version in `PRAGMA user_version`.
- Always use `INT` for integer type, and `TEXT` for text type,
  so that we could save a little space.  This does not affect the
  actual datatype (more precisely, type affinity) of the columns.
2025-01-26 00:19:54 +08:00
CismonX
35d4a93a41
backend_firefox: fix sandbox
- Allow fdatasync(), since it is used by SQLite when commiting.
- Move `PRAGMA quick_check` to backend_create(), since it sometimes
  calls stat() and cannot be sandboxed.
2025-01-25 21:15:57 +08:00
CismonX
10ad224b03
backend: rename backend_sync -> bookmark_sync 2025-01-24 23:07:22 +08:00
CismonX
623b4dd4f3
backend: rename backend_free -> backend_destroy 2025-01-24 09:12:41 +08:00
CismonX
3cb99fe85b
all: fix punctuation regarding "e.g." and "i.e."
Follow the convention of modern English grammar that
a comma should usually come after "e.g." and "i.e.".
2025-01-23 19:23:54 +08:00
CismonX
22263e48f2
backend: rename struct
`bookmarkfs_backend_init_resp` -> `bookmarkfs_backend_create_resp`,
since it is used for `backend_create` instead of `backend_init`.
2025-01-23 17:41:31 +08:00
CismonX
349877f9a3
backend_firefox: don't bother opening db readonly
Readonly db does not work well with WAL mode.
See <https://www.sqlite.org/wal.html#readonly>.
2025-01-14 19:44:34 +08:00
CismonX
38e33532f0
sandbox: remove redundant fusefd arg 2025-01-04 00:29:16 +08:00
CismonX
3e325a3934
ioctl: check if permd op is valid
A bad permd op should fail ioctl() with EINVAL instead of
invoking undefined behavior.
2025-01-02 18:53:12 +08:00
CismonX
cdf0ddfc53
init: prepare for Savannah 2024-12-31 18:09:03 +08:00