On Fri, Dec 28, 2018 at 3:07 PM Igor Korot <ikoro...@gmail.com> wrote:

> Hi,
>
> On Fri, Dec 28, 2018 at 4:51 PM patrick keshishian <pkesh...@gmail.com>
> wrote:
> >
> >
> > On Fri, Dec 28, 2018 at 2:00 PM Igor Korot <ikoro...@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 of bytes 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 and hence an invalid UTF-8
> sequence.
> >
> > Furthermore, your value[] array allocation is in error since
> wstring::length returns number of characters, not number of 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 hold the 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.
> >>
>

Reply via email to