mirror of
https://git.sr.ht/~cismonx/bookmarkfs
synced 2025-06-07 19:58:50 +00:00
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.
118 lines
3.5 KiB
C
118 lines
3.5 KiB
C
/**
|
|
* bookmarkfs/src/backend_util.h
|
|
* ----
|
|
*
|
|
* Copyright (C) 2024 CismonX <admin@cismon.net>
|
|
*
|
|
* This file is part of BookmarkFS.
|
|
*
|
|
* BookmarkFS is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* BookmarkFS is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with BookmarkFS. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef BOOKMARKFS_BACKEND_UTIL_H_
|
|
#define BOOKMARKFS_BACKEND_UTIL_H_
|
|
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
#include "defs.h"
|
|
|
|
#define BACKEND_OPT_ERR_BAD_KEY_ 0
|
|
#define BACKEND_OPT_ERR_BAD_VAL_ 1
|
|
#define BACKEND_OPT_ERR_HAS_VAL_ 2
|
|
#define BACKEND_OPT_ERR_NO_VAL_ 3
|
|
#define BACKEND_OPT_ERR_(err_type) \
|
|
print_backend_opt_err_(BACKEND_OPT_ERR_##err_type##_, key_, val_)
|
|
|
|
#define BACKEND_OPT_START(opts) \
|
|
for (; (opts) != NULL; (opts) = (opts)->next) { \
|
|
char const *key_ = (opts)->key; \
|
|
char const *val_ = (opts)->val; \
|
|
if (0);
|
|
#define BACKEND_OPT_END \
|
|
else return BACKEND_OPT_ERR_(BAD_KEY); \
|
|
}
|
|
#define BACKEND_OPT_KEY(name) else if (0 == strcmp(name, key_))
|
|
#define BACKEND_OPT_VAL(name) else if (0 == strcmp(name, val_))
|
|
#define BACKEND_OPT_VAL_START \
|
|
if (val_ == NULL) return BACKEND_OPT_ERR_(NO_VAL);
|
|
#define BACKEND_OPT_VAL_END else return BACKEND_OPT_ERR_(BAD_VAL);
|
|
#define BACKEND_OPT_BAD_VAL() BACKEND_OPT_ERR_(BAD_VAL)
|
|
#define BACKEND_OPT_NO_VAL \
|
|
if (val_ != NULL) return BACKEND_OPT_ERR_(HAS_VAL);
|
|
#define BACKEND_OPT_VAL_STR (val_)
|
|
|
|
#define FILENAME_BADCHAR -1
|
|
#define FILENAME_BADLEN -2
|
|
#define FILENAME_DOTDOT -3
|
|
|
|
/**
|
|
* The maximum valid seconds that a signed 64-bit integer can hold
|
|
* when converted to microseconds.
|
|
*
|
|
* Equals to `INT64_MAX / 1000000 - EPOCH_DIFF - 1`:
|
|
* - See the Chromium backend for `EPOCH_DIFF`.
|
|
* - Considering `tv_nsec`, subtract another second.
|
|
*/
|
|
#define TIMESPEC_SEC_MAX INT64_C(9211727563253)
|
|
#define valid_ts_sec(sec) ((sec) >= 0 && (sec) <= TIMESPEC_SEC_MAX)
|
|
|
|
/**
|
|
* Opens the parent directory of a file, and stores its basename
|
|
* to `basename_ptr`.
|
|
*
|
|
* NOTE: The function may modify `path`, and the pointer stored to
|
|
* `basename_ptr` is always within the address range of `path`.
|
|
*
|
|
* Returns the directory file descriptor if successful.
|
|
* On error, -1 is returned, and errno is set.
|
|
*/
|
|
int
|
|
basename_opendir (
|
|
char *path,
|
|
char **basename_ptr
|
|
);
|
|
|
|
FUNCATTR_COLD
|
|
int
|
|
print_backend_opt_err_ (
|
|
int err_type,
|
|
char const *key,
|
|
char const *val
|
|
);
|
|
|
|
/**
|
|
* Check if a string is a valid path component.
|
|
* If the string contains any NUL byte, the result is unspecified.
|
|
*
|
|
* Returns 0 if name is valid, FILENAME_* if not.
|
|
* If returning FILENAME_BADCHAR, stores the pointer to the first
|
|
* bad character to `end_ptr` unless it is NULL.
|
|
*/
|
|
int
|
|
validate_filename (
|
|
char const *str,
|
|
size_t str_len,
|
|
char const **end_ptr
|
|
);
|
|
|
|
int
|
|
validate_filename_fsck (
|
|
char const *str,
|
|
size_t str_len,
|
|
int *result_ptr,
|
|
uint64_t *extra_ptr
|
|
);
|
|
|
|
#endif /* defined(BOOKMARKFS_BACKEND_UTIL_H_) */
|