#include "basics.h" #include "reftable-fsck.h" #include "reftable-table.h" #include "stack.h" static bool table_has_valid_name(const char *name) { const char *ptr = name; char *endptr; /* strtoull doesn't set errno on success */ errno = 0; strtoull(ptr, &endptr, 16); if (errno) return false; ptr = endptr; if (*ptr != '-') return false; ptr++; strtoull(ptr, &endptr, 16); if (errno) return false; ptr = endptr; if (*ptr != '-') return false; ptr++; strtoul(ptr, &endptr, 16); if (errno) return false; ptr = endptr; if (strcmp(ptr, ".ref") && strcmp(ptr, ".log")) return false; return true; } typedef int (*table_check_fn)(struct reftable_table *table, reftable_fsck_report_fn report_fn, void *cb_data); static int table_check_name(struct reftable_table *table, reftable_fsck_report_fn report_fn, void *cb_data) { if (!table_has_valid_name(table->name)) { struct reftable_fsck_info info; info.error = REFTABLE_FSCK_ERROR_TABLE_NAME; info.msg = "invalid reftable table name"; info.path = table->name; return report_fn(&info, cb_data); } return 0; } static int table_checks(struct reftable_table *table, reftable_fsck_report_fn report_fn, reftable_fsck_verbose_fn verbose_fn UNUSED, void *cb_data) { table_check_fn table_check_fns[] = { table_check_name, NULL, }; int err = 0; for (size_t i = 0; table_check_fns[i]; i++) err |= table_check_fns[i](table, report_fn, cb_data); return err; } int reftable_fsck_check(struct reftable_stack *stack, reftable_fsck_report_fn report_fn, reftable_fsck_verbose_fn verbose_fn, void *cb_data) { struct reftable_buf msg = REFTABLE_BUF_INIT; int err = 0; for (size_t i = 0; i < stack->tables_len; i++) { reftable_buf_reset(&msg); reftable_buf_addstr(&msg, "Checking table: "); reftable_buf_addstr(&msg, stack->tables[i]->name); verbose_fn(msg.buf, cb_data); err |= table_checks(stack->tables[i], report_fn, verbose_fn, cb_data); } reftable_buf_release(&msg); return err; }