From 7713b8ccb0b207525e66ecf41dce12c62badb621 Mon Sep 17 00:00:00 2001 From: Ben Wiederhake Date: Sat, 17 Oct 2015 00:49:20 +0200 Subject: [PATCH] Fix endianess issues. --- portable_endian.h | 122 ++++++++++++++++++++++++++++++++++++++++++++++ tl-parser.c | 10 +++- 2 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 portable_endian.h diff --git a/portable_endian.h b/portable_endian.h new file mode 100644 index 0000000..da0d140 --- /dev/null +++ b/portable_endian.h @@ -0,0 +1,122 @@ +// "License": Public Domain +// I, Mathias Panzenböck, place this file hereby into the public domain. Use it at your own risk for whatever you like. +// In case there are jurisdictions that don't support putting things in the public domain you can also consider it to +// be "dual licensed" under the BSD, MIT and Apache licenses, if you want to. This code is trivial anyway. Consider it +// an example on how to get the endian conversion functions on different platforms. + +/* Originally cloned from https://gist.github.com/PkmX/63dd23f28ba885be53a5 + * Commit was: 1eca2ab34f2301b9641aa73d1016b951fff3fc39 + * Re-published at https://github.com/BenWiederhake/portable-endian.h to provide a means to submit patches and report issues. */ + +#ifndef PORTABLE_ENDIAN_H__ +#define PORTABLE_ENDIAN_H__ + +#if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) && !defined(__WINDOWS__) + +# define __WINDOWS__ + +#endif + +#if defined(__linux__) || defined(__CYGWIN__) + +# include + +#elif defined(__APPLE__) + +# include + +# define htobe16(x) OSSwapHostToBigInt16(x) +# define htole16(x) OSSwapHostToLittleInt16(x) +# define be16toh(x) OSSwapBigToHostInt16(x) +# define le16toh(x) OSSwapLittleToHostInt16(x) + +# define htobe32(x) OSSwapHostToBigInt32(x) +# define htole32(x) OSSwapHostToLittleInt32(x) +# define be32toh(x) OSSwapBigToHostInt32(x) +# define le32toh(x) OSSwapLittleToHostInt32(x) + +# define htobe64(x) OSSwapHostToBigInt64(x) +# define htole64(x) OSSwapHostToLittleInt64(x) +# define be64toh(x) OSSwapBigToHostInt64(x) +# define le64toh(x) OSSwapLittleToHostInt64(x) + +# define __BYTE_ORDER BYTE_ORDER +# define __BIG_ENDIAN BIG_ENDIAN +# define __LITTLE_ENDIAN LITTLE_ENDIAN +# define __PDP_ENDIAN PDP_ENDIAN + +#elif defined(__OpenBSD__) + +# include + +#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) + +# include + +# define be16toh(x) betoh16(x) +# define le16toh(x) letoh16(x) + +# define be32toh(x) betoh32(x) +# define le32toh(x) letoh32(x) + +# define be64toh(x) betoh64(x) +# define le64toh(x) letoh64(x) + +#elif defined(__WINDOWS__) + +# include +# include + +# if BYTE_ORDER == LITTLE_ENDIAN + +# define htobe16(x) htons(x) +# define htole16(x) (x) +# define be16toh(x) ntohs(x) +# define le16toh(x) (x) + +# define htobe32(x) htonl(x) +# define htole32(x) (x) +# define be32toh(x) ntohl(x) +# define le32toh(x) (x) + +# define htobe64(x) htonll(x) +# define htole64(x) (x) +# define be64toh(x) ntohll(x) +# define le64toh(x) (x) + +# elif BYTE_ORDER == BIG_ENDIAN + + /* that would be xbox 360 */ +# define htobe16(x) (x) +# define htole16(x) __builtin_bswap16(x) +# define be16toh(x) (x) +# define le16toh(x) __builtin_bswap16(x) + +# define htobe32(x) (x) +# define htole32(x) __builtin_bswap32(x) +# define be32toh(x) (x) +# define le32toh(x) __builtin_bswap32(x) + +# define htobe64(x) (x) +# define htole64(x) __builtin_bswap64(x) +# define be64toh(x) (x) +# define le64toh(x) __builtin_bswap64(x) + +# else + +# error byte order not supported + +# endif + +# define __BYTE_ORDER BYTE_ORDER +# define __BIG_ENDIAN BIG_ENDIAN +# define __LITTLE_ENDIAN LITTLE_ENDIAN +# define __PDP_ENDIAN PDP_ENDIAN + +#else + +# error platform not supported + +#endif + +#endif diff --git a/tl-parser.c b/tl-parser.c index a7ccf6b..4d9fe0c 100644 --- a/tl-parser.c +++ b/tl-parser.c @@ -35,6 +35,7 @@ #include #include #include +#include "portable_endian.h" #include "tl-parser-tree.h" #include "tl-parser.h" #include "tl-tl.h" @@ -62,6 +63,9 @@ int total_functions_num; #define talloc0(a) calloc(a,1) #define tstrdup(a) strdup(a) +typedef char error_int_must_be_4_byte[(sizeof (int) == 4) ? 1 : -1]; +typedef char error_long_long_must_be_8_byte[(sizeof (long long) == 8) ? 1 : -1]; + char curch; struct parse parse; @@ -2723,6 +2727,7 @@ int num = 0; void wint (int a) { // printf ("%d ", a); + a = htole32 (a); assert (write (__f, &a, 4) == 4); } @@ -2735,7 +2740,8 @@ void wstr (const char *s) { // printf ("\"%s\" ", s); int x = strlen (s); if (x <= 254) { - assert (write (__f, &x, 1) == 1); + unsigned char x_c = (unsigned char)x; + assert (write (__f, &x_c, 1) == 1); } else { fprintf (stderr, "String is too big...\n"); assert (0); @@ -2744,6 +2750,7 @@ void wstr (const char *s) { x ++; // The header, containing the length, which is 1 byte int t = 0; if (x & 3) { + // Let's hope it's truly zero on every platform wdata (&t, 4 - (x & 3)); } } else { @@ -2754,6 +2761,7 @@ void wstr (const char *s) { void wll (long long a) { // printf ("%lld ", a); + a = htole64 (a); assert (write (__f, &a, 8) == 8); }