From 20b317923b615cd6e7b91d14b8cc8adb4b0696f0 Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Tue, 3 Jan 2023 15:49:26 +0200 Subject: [PATCH] Extend PgQueryProtobuf.len to machine word size The len field is expected to be size_t from the protobuf side (see the definition of pg_query__parse_result__unpack()). Also, clients are expecting to be able to use size_t-like types when filling the PgQueryProtobuf structure. This is how this problem was discovered in pglast: deparse_protobuf(parse_sql_protobuf('select 1')) would always return '' on big-endian machines. deparse_protobuf() populated a 64-bit machine-word-sized len field, but libpg-query would only read an "int" from it, which is 32-bit only even on 64-bit machines. On big-endian machines, the "wrong" half of the integer is read, so the len is effectively always zeros. Close lelit/pglast#114. --- examples/scan.c | 2 +- pg_query.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/scan.c b/examples/scan.c index e7634dad..9360edf5 100644 --- a/examples/scan.c +++ b/examples/scan.c @@ -39,7 +39,7 @@ int main() { } else { scan_result = pg_query__scan_result__unpack(NULL, result.pbuf.len, (void *) result.pbuf.data); - printf(" version: %d, tokens: %ld, size: %d\n", scan_result->version, scan_result->n_tokens, result.pbuf.len); + printf(" version: %d, tokens: %ld, size: %zu\n", scan_result->version, scan_result->n_tokens, result.pbuf.len); for (j = 0; j < scan_result->n_tokens; j++) { scan_token = scan_result->tokens[j]; token_kind = protobuf_c_enum_descriptor_get_value(&pg_query__token__descriptor, scan_token->token); diff --git a/pg_query.h b/pg_query.h index 78f6dc89..ba926c3e 100644 --- a/pg_query.h +++ b/pg_query.h @@ -2,6 +2,7 @@ #define PG_QUERY_H #include +#include typedef struct { char* message; // exception message @@ -13,7 +14,7 @@ typedef struct { } PgQueryError; typedef struct { - unsigned int len; + size_t len; char* data; } PgQueryProtobuf;