-
-
Notifications
You must be signed in to change notification settings - Fork 250
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adjust StringInfo wrapper impl to match actual definition (#1457)
A commit that alters the definition of StringInfo was introduced about 2 months ago to Postgres: postgres/postgres@f0efa5a It contains the following comment: ``` * As a special case, a StringInfoData can be initialized with a read-only * string buffer. In this case "data" does not necessarily point at a * palloc'd chunk, and management of the buffer storage is the caller's * responsibility. maxlen is set to zero to indicate that this is the case. * Read-only StringInfoDatas cannot be appended to or reset. * Also, it is caller's option whether a read-only string buffer has a * terminating '\0' or not. This depends on the intended usage. ``` This will make the following sequence of Rust code completely unsound **by mere invocation** as of Postgres 17, even assuming the lifetime constraint is correct: ```rust let stringinfo: *mut pg_sys::StringInfoData = something_that_returns_ptr_to_stringinfodata(); let stringinfo: StringInfo<AllocatedByPostgres> = unsafe { StringInfoData::from_pg(stringinfo) }; let cstr_from_stringinfo: &'static CStr = stringinfo.into(); ``` However, that commit has its own remarks: ``` There were various places in our codebase which conjured up a StringInfo by manually assigning the StringInfo fields and setting the data field to point to some existing buffer. There wasn't much consistency here as to what fields like maxlen got set to and in one location we didn't correctly ensure that the buffer was correctly NUL terminated at len bytes, as per what was documented as required in stringinfo.h ``` ..."In one location we didn't correctly ensure that the buffer was correctly NUL terminated"? On actually reviewing the commit, in multiple places, the maximum len was previously set to -1 or other incorrect values to indicate similar sorts of "borrow-like" usages. In other words, the `max_len > len` invariant was not preserved either, so it was not impossible for the pointee buffer to actually end at exactly len N, instead of also having another byte available. While the only constructor for the StringInfoData wrapper is its `unsafe fn from_pg`, we were most certainly relying on this being true, and making comments as if we expected Postgres to not randomly pass us bogus data. In actuality, we find now that Postgres passes us bogus data all the time. As this guarantee has never actually been enforced, we should remove the implementation of `impl From<StringInfo<_>> for &'static CStr` immediately. This also means our Drop implementation has to go. A more direct API is offered instead via `StringInfo::leak_cstr`.
- Loading branch information
1 parent
e7112ed
commit 483606b
Showing
4 changed files
with
39 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters