diff --git a/src/common/xdr.cpp b/src/common/xdr.cpp index 73eb6a7eba0..6dd23d36fb8 100644 --- a/src/common/xdr.cpp +++ b/src/common/xdr.cpp @@ -444,40 +444,7 @@ bool_t xdr_int128(xdr_t* xdrs, Firebird::Int128* ip) #endif } - -bool_t xdr_enum(xdr_t* xdrs, xdr_op* ip) -{ -/************************************** - * - * x d r _ e n u m - * - ************************************** - * - * Functional description - * Map from external to internal representation (or vice versa). - * - **************************************/ - SLONG temp; - - switch (xdrs->x_op) - { - case XDR_ENCODE: - temp = (SLONG) *ip; - return PUTLONG(xdrs, &temp); - - case XDR_DECODE: - if (!GETLONG(xdrs, &temp)) - return FALSE; - *ip = (xdr_op) temp; - return TRUE; - - case XDR_FREE: - return TRUE; - } - - return FALSE; -} - +// xdr_enum is now a template function in xdr_proto.h bool_t xdr_float(xdr_t* xdrs, float* ip) { diff --git a/src/common/xdr_proto.h b/src/common/xdr_proto.h index 9a31846042e..fafbe96e753 100644 --- a/src/common/xdr_proto.h +++ b/src/common/xdr_proto.h @@ -31,11 +31,32 @@ bool_t xdr_datum(xdr_t*, const dsc*, UCHAR*); bool_t xdr_double(xdr_t*, double*); bool_t xdr_dec64(xdr_t*, Firebird::Decimal64*); bool_t xdr_dec128(xdr_t*, Firebird::Decimal128*); -bool_t xdr_int128(xdr_t*, Firebird::Int128*); -bool_t xdr_enum(xdr_t*, xdr_op*); bool_t xdr_float(xdr_t*, float*); bool_t xdr_int(xdr_t*, int*); +bool_t xdr_int128(xdr_t*, Firebird::Int128*); bool_t xdr_long(xdr_t*, SLONG*); + +// Template xdr_enum for type-safe enum serialization. +// Accepts any enum type, uses static_cast to avoid UB from reinterpret_cast. +template +inline bool_t xdr_enum(xdr_t* xdrs, EnumT* ip) +{ + SLONG temp; + switch (xdrs->x_op) + { + case XDR_ENCODE: + temp = static_cast(*ip); + return xdr_long(xdrs, &temp); + case XDR_DECODE: + if (!xdr_long(xdrs, &temp)) + return FALSE; + *ip = static_cast(temp); + return TRUE; + case XDR_FREE: + return TRUE; + } + return FALSE; +} bool_t xdr_opaque(xdr_t*, SCHAR*, unsigned); bool_t xdr_quad(xdr_t*, SQUAD*); bool_t xdr_short(xdr_t*, SSHORT*); diff --git a/src/remote/protocol.cpp b/src/remote/protocol.cpp index d48d2cc4c53..34a741906ed 100644 --- a/src/remote/protocol.cpp +++ b/src/remote/protocol.cpp @@ -292,7 +292,7 @@ bool_t xdr_protocol(RemoteXdr* xdrs, PACKET* p) DEBUG_XDR_PACKET(xdrs, p); - if (!xdr_enum(xdrs, reinterpret_cast(&p->p_operation))) + if (!xdr_enum(xdrs, &p->p_operation)) return P_FALSE(xdrs, p); #if COMPRESS_DEBUG > 1 @@ -320,9 +320,9 @@ bool_t xdr_protocol(RemoteXdr* xdrs, PACKET* p) case op_connect: { P_CNCT* connect = &p->p_cnct; - MAP(xdr_enum, reinterpret_cast(connect->p_cnct_operation)); + MAP(xdr_enum, connect->p_cnct_operation); MAP(xdr_short, reinterpret_cast(connect->p_cnct_cversion)); - MAP(xdr_enum, reinterpret_cast(connect->p_cnct_client)); + MAP(xdr_enum, connect->p_cnct_client); MAP(xdr_cstring_const, connect->p_cnct_file); MAP(xdr_short, reinterpret_cast(connect->p_cnct_count)); @@ -339,7 +339,7 @@ bool_t xdr_protocol(RemoteXdr* xdrs, PACKET* p) } MAP(xdr_short, reinterpret_cast(tail->p_cnct_version)); - MAP(xdr_enum, reinterpret_cast(tail->p_cnct_architecture)); + MAP(xdr_enum, tail->p_cnct_architecture); MAP(xdr_u_short, tail->p_cnct_min_type); MAP(xdr_u_short, tail->p_cnct_max_type); MAP(xdr_short, reinterpret_cast(tail->p_cnct_weight)); @@ -358,7 +358,7 @@ bool_t xdr_protocol(RemoteXdr* xdrs, PACKET* p) case op_accept: accept = &p->p_acpt; MAP(xdr_short, reinterpret_cast(accept->p_acpt_version)); - MAP(xdr_enum, reinterpret_cast(accept->p_acpt_architecture)); + MAP(xdr_enum, accept->p_acpt_architecture); MAP(xdr_u_short, accept->p_acpt_type); DEBUG_PRINTSIZE(xdrs, p->p_operation); return P_TRUE(xdrs, p); @@ -367,7 +367,7 @@ bool_t xdr_protocol(RemoteXdr* xdrs, PACKET* p) case op_cond_accept: accept_with_data = &p->p_acpd; MAP(xdr_short, reinterpret_cast(accept_with_data->p_acpt_version)); - MAP(xdr_enum, reinterpret_cast(accept_with_data->p_acpt_architecture)); + MAP(xdr_enum, accept_with_data->p_acpt_architecture); MAP(xdr_u_short, accept_with_data->p_acpt_type); MAP(xdr_cstring, accept_with_data->p_acpt_data); MAP(xdr_cstring, accept_with_data->p_acpt_plugin);