journal-gatewayd: fix handling of num_skip pointing beyond the last entry

When `num_skip` is supplied to the `Range` header, journal-gatewayd
always returns the very last record even though it should have been
skipped. This is because the `sd_journal_next_skip` always returns
non-zero value on the first call, leading to one iteration of the
`request_reader_entries` returning the last record.

To avoid this unexpected behavior, check that the number of lines we
have skipped by is not lower than the requested skip value. If it is,
then it means there are lines which should not be returned now -
decrement the n_skip counter then and return from the function, closing
the stream if follow flag is not set.

Fixes #37954
This commit is contained in:
Jan Čermák
2025-06-24 18:54:44 +02:00
committed by Yu Watanabe
parent f789b17e87
commit a7bfb9f76b
2 changed files with 20 additions and 2 deletions

View File

@@ -182,9 +182,21 @@ static ssize_t request_reader_entries(
if (m->n_skip < 0)
r = sd_journal_previous_skip(m->journal, (uint64_t) -m->n_skip + 1);
else if (m->n_skip > 0)
else if (m->n_skip > 0) {
r = sd_journal_next_skip(m->journal, (uint64_t) m->n_skip + 1);
else
if (r < 0) {
log_error_errno(r, "Failed to skip journal entries: %m");
return MHD_CONTENT_READER_END_WITH_ERROR;
}
/* We skipped beyond the end, make sure entries between the cursor and n_skip offset
* from it are not returned. */
if (r < m->n_skip + 1) {
m->n_skip -= r;
if (m->follow)
return 0;
return MHD_CONTENT_READER_END_OF_STREAM;
}
} else
r = sd_journal_next(m->journal);
if (r < 0) {

View File

@@ -82,6 +82,12 @@ timeout 5 curl -LSfs \
--header "Range: entries=:-20:10" \
http://localhost:19531/entries?follow >"$LOG_FILE"
jq -se "length == 10" "$LOG_FILE"
# Test positive skip beyond the last entry
curl -LSfs \
--header "Accept: application/json" \
--header "Range: entries=$TEST_CURSOR:1:1" \
http://localhost:19531/entries?SYSLOG_IDENTIFIER="$TEST_TAG" >"$LOG_FILE"
jq -se "length == 0" "$LOG_FILE"
# Check if the specified cursor refers to an existing entry and return just that entry
curl -LSfs \
--header "Accept: application/json" \