From cd648f9ef0cede7d50a34f055946b68a7e0633cd Mon Sep 17 00:00:00 2001 From: CismonX Date: Thu, 27 Feb 2025 23:22:09 +0800 Subject: [PATCH] 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()`. --- src/backend_firefox.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/backend_firefox.c b/src/backend_firefox.c index 5d03dfd..7184ff0 100644 --- a/src/backend_firefox.c +++ b/src/backend_firefox.c @@ -2089,9 +2089,11 @@ bookmark_do_list ( #define BOOKMARK_LIST_(col, join) \ "SELECT `b`.`id`, `b`.`position`, " col "FROM `moz_bookmarks` `b` " join \ "WHERE `b`.`parent` = ? AND `b`.`position` >= ? ORDER BY `b`.`position`" -#define BOOKMARK_LIST_NOJOIN_(col) BOOKMARK_LIST_(col ", `b`.`fk` ", ) +// Type: 1 -> bookmark; 2 -> folder; 3 -> separator. +#define BOOKMARK_LIST_NOJOIN_(col) BOOKMARK_LIST_(col ", 1 - `b`.`type` ", ) #define BOOKMARK_LIST_EX_COLS_ \ - "octet_length(`p`.`url`), `b`.`lastModified`, `p`.`last_visit_date`" + "ifnull(octet_length(`p`.`url`), -1), `b`.`lastModified`, " \ + "`p`.`last_visit_date`" #define BOOKMARK_LIST_EX_(col) \ BOOKMARK_LIST_(col ", " BOOKMARK_LIST_EX_COLS_ " ", \ "LEFT JOIN `moz_places` `p` ON `b`.`fk` = `p`.`id` ") @@ -2309,6 +2311,11 @@ bookmark_check_cb ( } ctx->next = position + 1; + if (-2 == sqlite3_column_int64(stmt, 3)) { + // skip separator + return 0; + } + size_t name_len = sqlite3_column_bytes(stmt, 2); char const *name = (char const *)sqlite3_column_text(stmt, 2); if (unlikely(name == NULL)) { @@ -2400,15 +2407,6 @@ bookmark_list_cb ( } entry.off = position + 1; - ssize_t len = -1; - if (SQLITE_INTEGER == sqlite3_column_type(stmt, 3)) { - len = sqlite3_column_int64(stmt, 3); - if (unlikely(len < 0)) { - goto fail; - } - } - entry.stat.value_len = len; - size_t name_len = sqlite3_column_bytes(stmt, 2); char const *name = (char const *)sqlite3_column_text(stmt, 2); if (unlikely(name == NULL)) { @@ -2449,6 +2447,7 @@ bookmark_list_cb ( set_name: entry.name = name; + entry.stat.value_len = sqlite3_column_int64(stmt, 3); if (ctx->with_stat) { msecs_to_timespec(&entry.stat.mtime, sqlite3_column_int64(stmt, 4)); msecs_to_timespec(&entry.stat.atime, sqlite3_column_int64(stmt, 5));