Compare commits

...

3 commits

Author SHA1 Message Date
CismonX
ba9a23c295
backend_firefox: refactor db query utils
- `DO_QUERY()` macro:
  * Pass stmt idx as argument instead of pointer.
  * Remove the `BEFORE_QUERY` argument.
- Shorter names for stmt idx.
2025-06-16 11:22:53 +08:00
CismonX
31f4311419
backend_firefox: misc refactor
- `mozorigin_get()`, `mozplace_addref()`: pass struct as argument.
- `parse_mozurl_host()`: rename to `parse_mozurl`; add comments;
  store parse results to argument of type `struct mozorigin`.
- Rename objects of type `struct mozXXX` from `XXX_cols` to `mX`.
- ...
2025-06-15 17:45:52 +08:00
CismonX
6fc165ff65
all: properly handle time_t on 32-bit platforms
Do not force 64-bit `time_t` on 32-bit platforms, since libfuse
does not do so.  Linking shared objects with incompatible types
breaks ABI, resulting in undefined behavior.

Instead, add run-time checks to make sure that timestamps do not
overflow.  If they do, set to `INT32_MAX`.

Also tidy up build scripts, tests, and the installation guide.
2025-06-14 11:43:03 +08:00
5 changed files with 301 additions and 372 deletions

View file

@ -166,19 +166,6 @@ Notes
In this case, the utility library will not be built from source,
and other components will link to the specified library instead.
### Targeting 32-bit Platforms
BookmarkFS requires 64-bit `off_t` and `time_t`, which may not be supported
on 32-bit platforms (e.g., i386 FreeBSD does not support 64-bit `time_t`).
If using Autoconf 2.72 or later, the configuration script automatically
performs checks and defines necessary macros, and fails if unsupported.
With legacy Autoconf, only `off_t` is checked.
To manually configure 64-bit `time_t`, add preprocessor flags
`-D_TIME_BITS=64` (or something equivalent, depending on the toolchain).
If unsupported, `make` will fail.
### FreeBSD and GNU libiconv
NOTE: You may skip this section if _not_ building the Chromium backend.

View file

@ -196,18 +196,7 @@ AS_VAR_IF([ac_have_largefile], [no], [
]))
])
m4_version_prereq([2.72], [
AC_SYS_YEAR2038
AS_VAR_IF([ac_have_year2038], [no], [
AC_MSG_ERROR(m4_normalize([
64-bit time_t is unsupported on this platform.
]))
])
], [
dnl fallback to compile-time check...
AX_COMPILE_CHECK_SIZEOF([time_t])
])
AX_COMPILE_CHECK_SIZEOF([time_t])
AX_COMPILE_CHECK_SIZEOF([uintptr_t], [#include <stdint.h>])
# -- Output --

View file

@ -58,17 +58,14 @@
#include "watcher.h"
#include "xstd.h"
#if defined(SIZEOF_TIME_T) && (SIZEOF_TIME_T != 8)
# error "64-bit time_t is required"
#endif
#define BACKEND_FILENAME_GUID ( 1u << 16 )
// Chromium uses Windows FILETIME epoch instead of Unix epoch.
// Chromium uses Windows FILETIME epoch, which is
// `((1970 - 1601) * 365 + 89) * 24 * 3600` seconds before the Unix epoch.
//
// See Chromium source code: /base/time/time.h
// (`base::Time::kTimeTToMicrosecondsOffset`)
#define EPOCH_DIFF ( (time_t)((1970 - 1601) * 365 + 89) * 24 * 3600 )
#define EPOCH_DIFF INT64_C(11644473600)
#define BOOKMARKS_ROOT_ID 0
@ -387,7 +384,7 @@ build_tsnode (
ts = &now;
}
time_t secs = ts->tv_sec + EPOCH_DIFF;
int64_t secs = ts->tv_sec + EPOCH_DIFF;
int64_t microsecs = secs * 1000000 + ts->tv_nsec / 1000;
char buf[32];
@ -1461,12 +1458,17 @@ parse_ts (
}
if (buf != NULL) {
time_t secs = microsecs / 1000000;
if (unlikely(secs < EPOCH_DIFF)) {
int64_t secs = microsecs / 1000000 - EPOCH_DIFF;
if (unlikely(secs < 0)) {
// Stay away from negative tv_sec
secs = EPOCH_DIFF;
secs = 0;
}
buf->tv_sec = secs - EPOCH_DIFF;
#if defined(SIZEOF_TIME_T) && (SIZEOF_TIME_T < 8)
else if (secs > INT32_MAX) {
secs = INT32_MAX;
}
#endif
buf->tv_sec = secs;
buf->tv_nsec = (microsecs % 1000000) * 1000;
}
return 0;

File diff suppressed because it is too large Load diff

View file

@ -31,13 +31,14 @@
#include <unistd.h>
#include "check_util.h"
#include "backend_util.h"
#include "frontend_util.h"
#include "prng.h"
// Forward declaration start
static int compare_timespec (struct timespec, struct timespec);
static int do_check_fs_times (int, int);
static void usecs_to_timespec (struct timespec *, uint32_t);
static void usecs_to_timespec (struct timespec *, uint64_t);
// Forward declaration end
static int
@ -113,9 +114,8 @@ do_check_fs_times (
ASSERT_NE(-1, compare_timespec(stat_buf.st_atim, now));
for (int i = 0; i < rounds; ++i) {
uint64_t bits = prng_rand();
usecs_to_timespec(&times[0], bits & 0xffffffff);
usecs_to_timespec(&times[1], bits >> 32);
usecs_to_timespec(&times[0], prng_rand());
usecs_to_timespec(&times[1], prng_rand());
ASSERT_EQ(0, futimens(fd, times));
ASSERT_EQ(0, fstat(fd, &stat_buf));
@ -142,9 +142,15 @@ do_check_fs_times (
static void
usecs_to_timespec (
struct timespec *ts_buf,
uint32_t usecs
uint64_t usecs
) {
ts_buf->tv_sec = usecs / 1000000;
int64_t secs = usecs / 1000000;
#if defined(SIZEOF_TIME_T) && (SIZEOF_TIME_T < 8)
secs %= (int64_t)INT32_MAX + 1;
#else
secs %= TIMESPEC_SEC_MAX + 1;
#endif
ts_buf->tv_sec = secs;
ts_buf->tv_nsec = (usecs % 1000000) * 1000;
}