Re: libpq bug? - Mailing list pgsql-general
From | Igor Korot |
---|---|
Subject | Re: libpq bug? |
Date | |
Msg-id | CA+FnnTw85P80PV5VYJebVWvZoDnM538sk6Qg9=6V44d6+rKYoQ@mail.gmail.com Whole thread Raw |
In response to | Re: libpq bug? (patrick keshishian <pkeshish@gmail.com>) |
Responses |
Re: libpq bug?
|
List | pgsql-general |
Hi, Patrick, Here is my new code: int PostgresDatabase::GetTableOwner (const std::wstring &schemaName, const std::wstring &tableName, std::wstring &owner, std::vector<std::wstring> &errorMsg) { int result = 0; std::wstring query = L"SELECT u.usename FROM pg_class c, pg_user u, pg_namespace n WHERE n.oid = c.relnamespace AND u.usesysid = c.relowner AND n.nspname = $1 AND relname = $2"; char *values[2]; values[0] = NULL, values[1] = NULL; int charlength1 = schemaName.length() * sizeof( wchar_t ), charlength2 = tableName.length() * sizeof( wchar_t ); values[0] = new char[schemaName.length() * sizeof( wchar_t ) + 1]; values[1] = new char[tableName.length() * sizeof( wchar_t ) + 1]; memset( values[0], '\0', schemaName.length() * sizeof( wchar_t ) + 1 ); memset( values[1], '\0', tableName.length() * sizeof( wchar_t ) + 1 ); strcpy( values[0], m_pimpl->m_myconv.to_bytes( schemaName.c_str() ).c_str() ); strcpy( values[1], m_pimpl->m_myconv.to_bytes( tableName.c_str() ).c_str() ); int len1 = (int) schemaName.length() * sizeof( wchar_t ); int len2 = (int) tableName.length() * sizeof( wchar_t ); int length[2] = { len1, len2 }; int formats[2] = { 1, 1 }; PGresult *res = PQexecParams( m_db, m_pimpl->m_myconv.to_bytes( query.c_str() ).c_str(), 2, NULL, values, length, formats, 1 ); ExecStatusType status = PQresultStatus( res ); if( status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK ) { result = 1; std::wstring err = m_pimpl->m_myconv.from_bytes( PQerrorMessage( m_db ) ); errorMsg.push_back( L"Error executing query: " + err ); PQclear( res ); } else { owner = m_pimpl->m_myconv.from_bytes( PQgetvalue( res, 0, 0 ) ); } return result; } The charlength2 variable contains the value of 8 and I'm still getting the same error. Any idea? Thank you. On Fri, Dec 28, 2018 at 5:40 PM patrick keshishian <pkeshish@gmail.com> wrote: > > On Fri, Dec 28, 2018 at 3:07 PM Igor Korot <ikorot01@gmail.com> wrote: >> >> Hi, >> >> On Fri, Dec 28, 2018 at 4:51 PM patrick keshishian <pkeshish@gmail.com> wrote: >> > >> > >> > On Fri, Dec 28, 2018 at 2:00 PM Igor Korot <ikorot01@gmail.com> wrote: >> >> >> >> Hi, ALL, >> >> Following code: >> >> >> >> int PostgresDatabase::GetTableOwner (const std::wstring &schemaName, >> >> const std::wstring &tableName, std::wstring &owner, >> >> std::vector<std::wstring> &errorMsg) >> >> { >> >> int result = 0; >> >> std::wstring query = L"SELECT u.usename FROM pg_class c, pg_user >> >> u, pg_namespace n WHERE n.oid = c.relnamespace AND u.usesysid = >> >> c.relowner AND n.nspname = $1 AND relname = $2"; >> >> char *values[2]; >> >> values[0] = NULL, values[1] = NULL; >> >> values[0] = new char[schemaName.length() + 1]; >> >> values[1] = new char[tableName.length() + 1]; >> >> memset( values[0], '\0', schemaName.length() + 1 ); >> >> memset( values[1], '\0', tableName.length() + 1 ); >> >> strcpy( values[0], m_pimpl->m_myconv.to_bytes( schemaName.c_str() >> >> ).c_str() ); >> >> strcpy( values[1], m_pimpl->m_myconv.to_bytes( tableName.c_str() >> >> ).c_str() ); >> >> int len1 = (int) schemaName.length(); >> >> int len2 = (int) tableName.length(); >> >> int length[2] = { len1, len2 }; >> >> int formats[2] = { 1, 1 }; >> >> PGresult *res = PQexecParams( m_db, m_pimpl->m_myconv.to_bytes( >> >> query.c_str() ).c_str(), 2, NULL, values, length, formats, 1 ); >> >> ExecStatusType status = PQresultStatus( res ); >> >> if( status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK ) >> >> { >> >> result = 1; >> >> std::wstring err = m_pimpl->m_myconv.from_bytes( >> >> PQerrorMessage( m_db ) ); >> >> errorMsg.push_back( L"Error executing query: " + err ); >> >> PQclear( res ); >> >> } >> >> else >> >> { >> >> owner = m_pimpl->m_myconv.from_bytes( PQgetvalue( res, 0, 0 ) ); >> >> } >> >> return result; >> >> } >> >> >> >> when ran with the call of >> >> >> >> GetTableOwner( "public", "abcß", owner, errorMsg ); >> >> >> >> returns: >> >> >> >> ERROR: Invalid byte sequence for encoding UTF8. >> >> >> >> Does this mean I found the bug in the library? >> > >> > >> > The bug is in your C++ code. "abcß" as tableName.lenght() (wstring) returns 4 (as in four characters) not number ofbytes required to represent the intended string: 61 62 63 c3 9f >> > Since the last character is a 2 bytes in length. Therefore, your call to PQexecParams() specifies a shorter length andhence an invalid UTF-8 sequence. >> > >> > Furthermore, your value[] array allocation is in error since wstring::length returns number of characters, not numberof bytes. so you will end up with buffer-overflows. >> >> So I should use >> https://stackoverflow.com/questions/9278723/how-can-i-get-the-byte-size-of-stdwstring >> in both places? > > > size() also returns 4. If you multiply it with sizeof(wchar_t) you will end up with maximum buffers size necessary to holdthe string (minus terminating \0), but not the correct length you are after. I am unsure of the "correct" C++ solution. > > Sorry, > --patrick > > >> >> Thank you. >> >> > >> > HTH, >> > --patrick >> > >> > >> >> >> >> Any idea what I can do? >> >> >> >> Thank you. >> >>
pgsql-general by date: