Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ Makefile.in
report.coverage
TAGS
t/test-merge.sh
cscope.out
tags
18 changes: 10 additions & 8 deletions mtbl/block.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
*/

// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
//
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
Expand All @@ -32,7 +32,7 @@
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Expand Down Expand Up @@ -202,7 +202,9 @@ static bool
parse_next_key(struct block_iter *bi)
{
bi->current = next_entry_offset(bi);
uint8_t *p = bi->data + bi->current; uint8_t *limit = bi->data + bi->restarts;
uint8_t *p = bi->data + bi->current;
uint8_t *limit = bi->data + bi->restarts;

if (p >= limit) {
/* no more entries to return, mark as invalid */
bi->current = bi->restarts;
Expand All @@ -214,7 +216,7 @@ parse_next_key(struct block_iter *bi)
uint32_t shared, non_shared, value_length;
p = decode_entry(p, limit, &shared, &non_shared, &value_length);
assert(!(p == NULL || ubuf_size(bi->key) < shared));

ubuf_clip(bi->key, shared);
ubuf_append(bi->key, p, non_shared);
bi->next = p + non_shared + value_length;
Expand All @@ -241,7 +243,7 @@ block_iter_seek_to_first(struct block_iter *bi)
parse_next_key(bi);
}

void
void
block_iter_seek_to_last(struct block_iter *bi)
{
seek_to_restart_point(bi, bi->num_restarts - 1);
Expand All @@ -268,7 +270,7 @@ block_iter_seek(struct block_iter *bi, const uint8_t *target, size_t target_len)
uint32_t start_ri = bi->restart_index; /* Current key is in this restart-block. */
bool from_start = true; /* Search from start of restart-block? */

/*
/*
* If the restart_index is not zero and not equal to the number of
* restarts, then begin with galloping search in the restart array to find
* the first restart point with a key >= target, otherwise just do binary
Expand Down Expand Up @@ -352,7 +354,7 @@ block_iter_next(struct block_iter *bi)
return (block_iter_valid(bi));
}

void
void
block_iter_prev(struct block_iter *bi)
{
assert(block_iter_valid(bi));
Expand Down
13 changes: 8 additions & 5 deletions mtbl/compression.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*
* Copyright (c) 2026 DomainTools LLC
* Copyright (c) 2012, 2014-2017, 2021 by Farsight Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -258,7 +259,7 @@ _mtbl_compress_zstd(
compression_level = ZSTD_maxCLevel();

zstd_size = ZSTD_compressBound(input_size);
if (zstd_size < INT_MAX/2) {
if (zstd_size < SIZE_MAX/2) {
/**
* "Compression runs faster if `dstCapacity` >=
* `ZSTD_compressBound(srcSize)`."
Expand Down Expand Up @@ -390,13 +391,14 @@ _mtbl_decompress_zstd(
{
size_t ret = 0;

if (input_size > INT_MAX)
unsigned long long decompressed_size = ZSTD_getFrameContentSize(input, input_size);
if (decompressed_size == ZSTD_CONTENTSIZE_UNKNOWN || decompressed_size == ZSTD_CONTENTSIZE_ERROR) {
return (mtbl_res_failure);

*output_size = (size_t) ZSTD_getFrameContentSize(input, input_size);
if (*output_size <= 0)
} else if (decompressed_size > SIZE_MAX) {
return (mtbl_res_failure);
}

*output_size = (size_t) decompressed_size;
*output = my_malloc(*output_size);

ret = ZSTD_decompress(
Expand Down Expand Up @@ -446,6 +448,7 @@ _mtbl_decompress_zlib(
size_t *output_size)
{
int zret;

z_stream zs = {
.avail_in = 0,
.next_in = Z_NULL,
Expand Down
15 changes: 10 additions & 5 deletions mtbl/reader.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 DomainTools LLC
* Copyright (c) 2022, 2026 DomainTools LLC
* Copyright (c) 2012-2018 by Farsight Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -224,11 +224,13 @@ mtbl_reader_init(const char *fname, const struct mtbl_reader_options *opt)
int fd;

fd = open(fname, O_RDONLY);
if (fd < 0)
if (fd < 0) {
return (NULL);
}

r = mtbl_reader_init_fd(fd, opt);
close(fd);

close(fd);
return (r);
}

Expand Down Expand Up @@ -455,7 +457,7 @@ reader_iter_seek(void *v,
const uint8_t *key, size_t len_key)
{
struct reader_iter *it = (struct reader_iter *) v;

const uint8_t *ikey, *ival;
size_t len_ikey, len_ival;
uint64_t new_offset;
Expand All @@ -475,7 +477,7 @@ reader_iter_seek(void *v,
mtbl_varint_decode64(ival, &new_offset);

/* We can skip decoding a new block if our new key is within the
* currently-decoded block. */
* currently-decoded block. */
if (it->b == NULL || it->block_offset != new_offset) {
block_destroy(&it->b);
block_iter_destroy(&it->bi);
Expand Down Expand Up @@ -515,7 +517,10 @@ reader_iter_next(void *v,
block_iter_destroy(&it->bi);
if (!block_iter_next(it->index_iter))
return (mtbl_res_failure);

it->b = get_block_at_index(it->r, it->index_iter);
assert(it->b != NULL);

it->bi = block_iter_init(it->b);
block_iter_seek_to_first(it->bi);
it->valid = block_iter_get(it->bi, key, len_key, val, len_val);
Expand Down
16 changes: 12 additions & 4 deletions mtbl/sorter.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*
* Copyright (c) 2026 DomainTools LLC
* Copyright (c) 2012-2016 by Farsight Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -139,6 +140,7 @@ mtbl_sorter_init(const struct mtbl_sorter_options *opt)
if (s->opt.pool != NULL) {
s->pool = s->opt.pool->pool;
s->rhandler = result_handler_init(_collect_readers_cb, s);
assert(s->rhandler != NULL);
}

return (s);
Expand Down Expand Up @@ -184,7 +186,8 @@ _mtbl_sorter_write_chunk(struct entry_batch *b)
char template[64];

/* Temporary file creation: */
sprintf(template, "/.mtbl.%ld.XXXXXX", (long)getpid());
(void) snprintf(template, sizeof(template), "/.mtbl.%ld.XXXXXX", (long)getpid());

ubuf *tmp_fname = ubuf_init(strlen(s->opt.tmp_dname) + strlen(template) + 1);
ubuf_append(tmp_fname, (uint8_t *) s->opt.tmp_dname, strlen(s->opt.tmp_dname));
ubuf_append(tmp_fname, (uint8_t *) template, strlen(template));
Expand All @@ -198,7 +201,10 @@ _mtbl_sorter_write_chunk(struct entry_batch *b)

struct mtbl_writer_options *wopt = mtbl_writer_options_init();
mtbl_writer_options_set_compression(wopt, MTBL_COMPRESSION_SNAPPY);

struct mtbl_writer *w = mtbl_writer_init_fd(fd, wopt);
assert(w != NULL);

mtbl_writer_options_destroy(&wopt);

/* Sort and add sorter entries to the temporary file writer. */
Expand All @@ -221,6 +227,10 @@ _mtbl_sorter_write_chunk(struct entry_batch *b)
entry_val(next_ent), next_ent->len_val,
&merge_val, &len_merge_val);
if (merge_val == NULL) {
for (size_t j = i; j < entry_vec_size(b->entries); j++) {
free(entry_vec_value(b->entries, j));
}
entry_vec_destroy(&b->entries);
free(b);
mtbl_writer_destroy(&w);
return (NULL);
Expand All @@ -241,9 +251,7 @@ _mtbl_sorter_write_chunk(struct entry_batch *b)
}
}

res = mtbl_writer_add(w,
entry_key(ent), ent->len_key,
entry_val(ent), ent->len_val);
res = mtbl_writer_add(w, entry_key(ent), ent->len_key, entry_val(ent), ent->len_val);
free(ent);
if (res != mtbl_res_success)
break;
Expand Down
17 changes: 13 additions & 4 deletions mtbl/threadpool.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2024 DomainTools LLC
* Copyright (c) 2024, 2026 DomainTools LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -165,6 +165,7 @@ static struct thread *
threadpool_next(struct threadpool *pool)
{
struct thread *thr = NULL;
int ret;

pthread_mutex_lock(&pool->m);

Expand All @@ -190,7 +191,9 @@ threadpool_next(struct threadpool *pool)
thr->pool = pool;
pthread_mutex_init(&thr->m, NULL);
pthread_cond_init(&thr->c, NULL);
pthread_create(&thr->t, NULL, thread_worker, thr);

ret = pthread_create(&thr->t, NULL, thread_worker, thr);
assert(ret == 0);
}

return thr;
Expand All @@ -213,6 +216,7 @@ threadpool_dispatch(struct threadpool *pool,
struct resultq *rq = rh->rq;
struct thread *thr = threadpool_next(pool);

assert(thr != NULL);
assert(!thr->running);
assert(thr->next == NULL);

Expand Down Expand Up @@ -378,11 +382,14 @@ struct result_handler *
result_handler_init(result_cb cb, void *cbdata)
{
struct result_handler *rh = calloc(1, sizeof(*rh));
int ret;

rh->rq = resultq_init();
rh->cb = cb;
rh->cbdata = cbdata;
pthread_create(&rh->thread, NULL, result_worker, rh);

ret = pthread_create(&rh->thread, NULL, result_worker, rh);
assert(ret == 0);

return rh;
}
Expand All @@ -391,7 +398,9 @@ void
result_handler_destroy(struct result_handler **prh)
{
struct result_handler *rh = *prh;
if (rh == NULL) return;
if (rh == NULL)
return;

resultq_finish(rh->rq);
pthread_join(rh->thread, NULL);
free(rh);
Expand Down
7 changes: 5 additions & 2 deletions mtbl/writer.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,10 @@ mtbl_writer_init_fd(int orig_fd, const struct mtbl_writer_options *opt)
* Start writing from the current offset. This allows mtbl's callers
* to reserve some initial bytes in the file.
*/
w->last_offset = lseek(fd, 0, SEEK_CUR);
w->pending_offset = w->last_offset;
off_t offset = lseek(fd, 0, SEEK_CUR);
assert(offset != (off_t)-1);

w->pending_offset = (uint64_t)offset;
w->last_key = ubuf_init(256);
w->m.file_version = MTBL_FORMAT_V2;
w->m.compression_algorithm = w->opt.compression_type;
Expand All @@ -175,6 +177,7 @@ mtbl_writer_init_fd(int orig_fd, const struct mtbl_writer_options *opt)
if (w->opt.pool != NULL) {
w->pool = w->opt.pool->pool;
w->rhandler = result_handler_init(_write_data_block_wrapper, w);
assert(w->rhandler != NULL);
}

return (w);
Expand Down
Loading