Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix segfault with empty numrange during from_datum() #1918

Merged
Show file tree
Hide file tree
Changes from 2 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
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ jobs:
echo ""

echo "----- Remove old postgres -----"
sudo apt remove -y '^postgres.*' '^libpq.*' '^clang.*' '^llvm.*' '^libclang.*' '^libllvm.*' '^mono-llvm.*'
sudo apt remove -y '^postgres.*' '^libpq.*' '^clang.*' '^llvm.*' '^libclang.*' '^libllvm.*'
echo ""

echo "----- Install system dependencies -----"
Expand Down Expand Up @@ -395,7 +395,7 @@ jobs:
echo ""

echo "----- Remove old postgres -----"
sudo apt remove -y '^postgres.*' '^libpq.*' '^clang.*' '^llvm.*' '^libclang.*' '^libllvm.*' '^mono-llvm.*'
sudo apt remove -y '^postgres.*' '^libpq.*' '^clang.*' '^llvm.*' '^libclang.*' '^libllvm.*'
echo ""

echo "----- Install system dependencies -----"
Expand Down
8 changes: 8 additions & 0 deletions pgrx-tests/src/tests/range_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,14 @@ mod tests {
assert_eq!(matched, Ok(Some(true)));
}

#[pg_test]
fn test_empty_anynumeric_range() {
let matched = Spi::get_one::<Range<AnyNumeric>>(
"SELECT accept_range_numeric('[10.5, 10.5)'::numrange)",
);
assert_eq!(matched, Ok(Some(Range::empty())));
}

#[pg_test]
fn test_accept_range_date() {
let matched =
Expand Down
18 changes: 13 additions & 5 deletions pgrx/src/datum/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,18 +348,26 @@ where
&mut is_empty,
);

// SAFETY: The lower_bound/upper_bound RangeBound value's .val will be a valid Datum of the T type
// If the range is_empty or either bound is infinite then .val = (Datum) 0
let lower = RangeBound::from_pg(lower_bound);
let upper = RangeBound::from_pg(upper_bound);
let range = if is_empty {
// empty ranges cannot go through `RangeBound::from_pg()` as the bound's `.val`
// Datum will be zero, and for a pass-by-reference range type, that's an instant segfault
Range::empty()
} else {
// SAFETY: The lower_bound/upper_bound RangeBound value's .val will be a valid Datum of the T type
// If the range is_empty or either bound is infinite then .val = (Datum) 0, which we handled above
let lower = RangeBound::from_pg(lower_bound);
let upper = RangeBound::from_pg(upper_bound);

Range { inner: Some((lower, upper)) }
};

if !std::ptr::eq(ptr, range_type.cast()) {
// SAFETY: range_type was allocated by Postgres in the call to
// pg_detoast_datum above, so we know it's a valid pointer and needs to be freed
pg_sys::pfree(range_type.cast());
}

Some(Range { inner: if is_empty { None } else { Some((lower, upper)) } })
Some(range)
}
}
}
Expand Down
Loading