-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Unwrap on from_utf8 causes panic with non-UTF-8 database server/client encodings #1144
Comments
This should be impossible. Something else must be going on. The data we get back for an error message must be in the client encoding which SQLx sets to UTF-8. What are some more details about your environment? Windows? How is Postgres running and what version of postgres? |
I've used a MRE repo (branch sql-windows-problems-empty) presented by @ShagonRU and I can confirm I could reproduce it locally: I'm using non-russian en-US locale everywhere so it must be a problem with |
Oh I believe it's happening. I'm just a little floored that it is. Documentation has been known to lie and postgres docs are quite bad. I'll see what I can figure out. Thank you for the expanded details. |
Looks like (lldb) p buf
(bytes::bytes::Bytes) $13 = {
ptr = 0x5600cecdc6c0c253 ""
len = 3621738852849566022
data = (p = core::cell::UnsafeCell<mut tuple<>*> @ 0x000001e090da26a0)
vtable = 0xe5f2e0e2eee7fceb
}
(lldb) x 0x5600cecdc6c0c253
error: Invalid access to memory location. But it could be a debugger mistake as well Debug print gives: [sqlx-core\src\postgres\message\response.rs:137] buf.len() = 175
[sqlx-core\src\postgres\message\response.rs:139] &buf[v.0 as usize..v.1 as usize] = [
194,
192,
198,
205,
206,
] |
I think I decoded the output. Response is
Decoding as WIN1251
Meaning it's an auth error which is in WIN1251 for unknown reason |
I think I've reproduced it. Try to login with invalid credentials, on windows (it's important, I couldn't reproduce it on linux machine). You will get:
Now go to the In a nutshell: You can't expect database returning responses in Alternatively (if you don't want to depend on crates for parsing different locales. Could be hidden under feature gate though) you can just invent another enum variant See It actually knows that response is not guaranteed to be UTF8 |
Sorry for a longread, I just was investigating this for several hours and was posting my insights here. The problem arises from incompatibilty between expectations that DB always returns responses in This gap should be filled somehow. Probably via |
I think proper way may be someting like:
Can if affect real time performance? I don't know. But in can be hidden by the feature flag.
|
Here is a relevant thread in the postgres mailing list: https://postgrespro.com/list/thread-id/1896813 It seems that errors during startup, notably before authentication, are returned in whatever encoding the server is configured for, regardless of the client encoding. |
This seems to be a fairly common issue actually. Drivers that have the problem: |
Found how JDBC fixed this: zemian/pgjdbc@bd6de1b#diff-92be561701c813957ebca8ca97c2a1e3e0eb9a822c4681dcd2cc0ddfcb34451e Basically this can only happen for auth errors during connection start-up and will only be FATAL errors. This limits the problem domain a lot. And JDBC then "predicts" the encoding using what it found for |
I just hope it's not lost on anyone how hilarious of a hack this is. |
I have the same error with the query macro, for example this |
@cdecompilador the easiest way to solve the issue right now is set encoding on server to be latin. The easiest way is set |
thread 'main' panicked at 'called severity_s = from_utf8(&buf[v.0 as usize..v.1 as usize])
.unwrap()
.try_into()
.ok(); |
If your database is installed on windows, you can comment out the code from b's'to b'c' and try again |
Instead of trying to sniff the encoding of the string, I think we should just detect this condition and emit a meaningful error message. |
Environment
Describing problem
If the postgres database has an encoding other than UTF-8, sqlx cannot connect to it due to an error in converting the message bytes to utf-8 encoding. Sample code:
What is in the dsn does not matter.
When I run this code, I get this:
Full stacktrace is available here - https://gist.github.com/ShagonRU/6bff4316a33895021b3aaed8554be16a
===
Next are my assumptions based on stacktrace.
After getting error (or another response) from database, this (
sqlx-core-0.5.1\src\postgres\message\response.rs:139:26
) code panics:Decode uses this trait impl (
sqlx-core-0.5.1\src\io\decode.rs:13:9
):Here is called this decode (
sqlx-core-0.5.1\src\postgres\connection\stream.rs:95:48
):So. As a result, If the database is not in UTF-8 encoding, then the user will simply get panic and will not be able to do anything about it. There is also no explanation anywhere about this moment. Moreover, as will be shown in the example above, the server can be in UTF-8 encoding, but if the client is not in it, there will be the same panic.
For example - my docker container with postgres:
And i getting the same error as with my local postgres.
I can only connect to a remote server from my system. (fortunately I have remote server, as well as the second non-Windows system, but this is still confusing)
Possible solutions
.unwrap()
and return correct error about encoding (???, i don'n know what user can do with this error)The text was updated successfully, but these errors were encountered: