git/reftable/reftable-error.h
Karthik Nayak 017bd89239 reftable: prevent 'update_index' changes after adding records
The function `reftable_writer_set_limits()` allows updating the
'min_update_index' and 'max_update_index' of a reftable writer. These
values are written to both the writer's header and footer.

Since the header is written during the first block write, any subsequent
changes to the update index would create a mismatch between the header
and footer values. The footer would contain the newer values while the
header retained the original ones.

To protect against this bug, prevent callers from updating these values
after any record is written. To do this, modify the function to return
an error whenever the limits are modified after any record adds. Check
for record adds within `reftable_writer_set_limits()` by checking the
`last_key` and `next` variable. The former is updated after each record
added, but is reset at certain points. The latter is set after writing
the first block.

Modify all callers of the function to anticipate a return type and
handle it accordingly. Add a unit test to also ensure the function
returns the error as expected.

Helped-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-01-22 09:51:36 -08:00

71 lines
1.9 KiB
C

/*
Copyright 2020 Google LLC
Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file or at
https://developers.google.com/open-source/licenses/bsd
*/
#ifndef REFTABLE_ERROR_H
#define REFTABLE_ERROR_H
/*
* Errors in reftable calls are signaled with negative integer return values. 0
* means success.
*/
enum reftable_error {
/* Unexpected file system behavior */
REFTABLE_IO_ERROR = -2,
/* Format inconsistency on reading data */
REFTABLE_FORMAT_ERROR = -3,
/* File does not exist. Returned from block_source_from_file(), because
* it needs special handling in stack.
*/
REFTABLE_NOT_EXIST_ERROR = -4,
/* Trying to access locked data. */
REFTABLE_LOCK_ERROR = -5,
/* Misuse of the API:
* - on writing a record with NULL refname.
* - on writing a record before setting the writer limits.
* - on writing a reftable_ref_record outside the table limits
* - on writing a ref or log record before the stack's
* next_update_inde*x
* - on writing a log record with multiline message with
* exact_log_message unset
* - on reading a reftable_ref_record from log iterator, or vice versa.
*
* When a call misuses the API, the internal state of the library is
* kept unchanged.
*/
REFTABLE_API_ERROR = -6,
/* Decompression error */
REFTABLE_ZLIB_ERROR = -7,
/* Wrote a table without blocks. */
REFTABLE_EMPTY_TABLE_ERROR = -8,
/* Invalid ref name. */
REFTABLE_REFNAME_ERROR = -10,
/* Entry does not fit. This can happen when writing outsize reflog
messages. */
REFTABLE_ENTRY_TOO_BIG_ERROR = -11,
/* Trying to write out-of-date data. */
REFTABLE_OUTDATED_ERROR = -12,
/* An allocation has failed due to an out-of-memory situation. */
REFTABLE_OUT_OF_MEMORY_ERROR = -13,
};
/* convert the numeric error code to a string. The string should not be
* deallocated. */
const char *reftable_error_str(int err);
#endif