mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-20 07:16:55 +00:00
utils: avoid unexpected side-effects of GST_WRITE_* macros
Make sure the data argument is only evaluated once.
This commit is contained in:
parent
22b7c0bf58
commit
0cbe23995f
2 changed files with 119 additions and 34 deletions
|
@ -274,14 +274,15 @@ static inline guint64 __gst_fast_read_swap64(const guint8 *v) {
|
|||
* Store a 64 bit unsigned integer value in big endian format into the memory buffer.
|
||||
*/
|
||||
#define GST_WRITE_UINT64_BE(data, num) do { \
|
||||
_GST_PUT (data, 0, 64, 56, num); \
|
||||
_GST_PUT (data, 1, 64, 48, num); \
|
||||
_GST_PUT (data, 2, 64, 40, num); \
|
||||
_GST_PUT (data, 3, 64, 32, num); \
|
||||
_GST_PUT (data, 4, 64, 24, num); \
|
||||
_GST_PUT (data, 5, 64, 16, num); \
|
||||
_GST_PUT (data, 6, 64, 8, num); \
|
||||
_GST_PUT (data, 7, 64, 0, num); \
|
||||
gpointer __put_data = data; \
|
||||
_GST_PUT (__put_data, 0, 64, 56, num); \
|
||||
_GST_PUT (__put_data, 1, 64, 48, num); \
|
||||
_GST_PUT (__put_data, 2, 64, 40, num); \
|
||||
_GST_PUT (__put_data, 3, 64, 32, num); \
|
||||
_GST_PUT (__put_data, 4, 64, 24, num); \
|
||||
_GST_PUT (__put_data, 5, 64, 16, num); \
|
||||
_GST_PUT (__put_data, 6, 64, 8, num); \
|
||||
_GST_PUT (__put_data, 7, 64, 0, num); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
|
@ -292,14 +293,15 @@ static inline guint64 __gst_fast_read_swap64(const guint8 *v) {
|
|||
* Store a 64 bit unsigned integer value in little endian format into the memory buffer.
|
||||
*/
|
||||
#define GST_WRITE_UINT64_LE(data, num) do { \
|
||||
_GST_PUT (data, 0, 64, 0, num); \
|
||||
_GST_PUT (data, 1, 64, 8, num); \
|
||||
_GST_PUT (data, 2, 64, 16, num); \
|
||||
_GST_PUT (data, 3, 64, 24, num); \
|
||||
_GST_PUT (data, 4, 64, 32, num); \
|
||||
_GST_PUT (data, 5, 64, 40, num); \
|
||||
_GST_PUT (data, 6, 64, 48, num); \
|
||||
_GST_PUT (data, 7, 64, 56, num); \
|
||||
gpointer __put_data = data; \
|
||||
_GST_PUT (__put_data, 0, 64, 0, num); \
|
||||
_GST_PUT (__put_data, 1, 64, 8, num); \
|
||||
_GST_PUT (__put_data, 2, 64, 16, num); \
|
||||
_GST_PUT (__put_data, 3, 64, 24, num); \
|
||||
_GST_PUT (__put_data, 4, 64, 32, num); \
|
||||
_GST_PUT (__put_data, 5, 64, 40, num); \
|
||||
_GST_PUT (__put_data, 6, 64, 48, num); \
|
||||
_GST_PUT (__put_data, 7, 64, 56, num); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
|
@ -310,10 +312,11 @@ static inline guint64 __gst_fast_read_swap64(const guint8 *v) {
|
|||
* Store a 32 bit unsigned integer value in big endian format into the memory buffer.
|
||||
*/
|
||||
#define GST_WRITE_UINT32_BE(data, num) do { \
|
||||
_GST_PUT (data, 0, 32, 24, num); \
|
||||
_GST_PUT (data, 1, 32, 16, num); \
|
||||
_GST_PUT (data, 2, 32, 8, num); \
|
||||
_GST_PUT (data, 3, 32, 0, num); \
|
||||
gpointer __put_data = data; \
|
||||
_GST_PUT (__put_data, 0, 32, 24, num); \
|
||||
_GST_PUT (__put_data, 1, 32, 16, num); \
|
||||
_GST_PUT (__put_data, 2, 32, 8, num); \
|
||||
_GST_PUT (__put_data, 3, 32, 0, num); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
|
@ -324,10 +327,11 @@ static inline guint64 __gst_fast_read_swap64(const guint8 *v) {
|
|||
* Store a 32 bit unsigned integer value in little endian format into the memory buffer.
|
||||
*/
|
||||
#define GST_WRITE_UINT32_LE(data, num) do { \
|
||||
_GST_PUT (data, 0, 32, 0, num); \
|
||||
_GST_PUT (data, 1, 32, 8, num); \
|
||||
_GST_PUT (data, 2, 32, 16, num); \
|
||||
_GST_PUT (data, 3, 32, 24, num); \
|
||||
gpointer __put_data = data; \
|
||||
_GST_PUT (__put_data, 0, 32, 0, num); \
|
||||
_GST_PUT (__put_data, 1, 32, 8, num); \
|
||||
_GST_PUT (__put_data, 2, 32, 16, num); \
|
||||
_GST_PUT (__put_data, 3, 32, 24, num); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
|
@ -338,9 +342,10 @@ static inline guint64 __gst_fast_read_swap64(const guint8 *v) {
|
|||
* Store a 24 bit unsigned integer value in big endian format into the memory buffer.
|
||||
*/
|
||||
#define GST_WRITE_UINT24_BE(data, num) do { \
|
||||
_GST_PUT (data, 0, 32, 16, num); \
|
||||
_GST_PUT (data, 1, 32, 8, num); \
|
||||
_GST_PUT (data, 2, 32, 0, num); \
|
||||
gpointer __put_data = data; \
|
||||
_GST_PUT (__put_data, 0, 32, 16, num); \
|
||||
_GST_PUT (__put_data, 1, 32, 8, num); \
|
||||
_GST_PUT (__put_data, 2, 32, 0, num); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
|
@ -351,9 +356,10 @@ static inline guint64 __gst_fast_read_swap64(const guint8 *v) {
|
|||
* Store a 24 bit unsigned integer value in little endian format into the memory buffer.
|
||||
*/
|
||||
#define GST_WRITE_UINT24_LE(data, num) do { \
|
||||
_GST_PUT (data, 0, 32, 0, num); \
|
||||
_GST_PUT (data, 1, 32, 8, num); \
|
||||
_GST_PUT (data, 2, 32, 16, num); \
|
||||
gpointer __put_data = data; \
|
||||
_GST_PUT (__put_data, 0, 32, 0, num); \
|
||||
_GST_PUT (__put_data, 1, 32, 8, num); \
|
||||
_GST_PUT (__put_data, 2, 32, 16, num); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
|
@ -364,8 +370,9 @@ static inline guint64 __gst_fast_read_swap64(const guint8 *v) {
|
|||
* Store a 16 bit unsigned integer value in big endian format into the memory buffer.
|
||||
*/
|
||||
#define GST_WRITE_UINT16_BE(data, num) do { \
|
||||
_GST_PUT (data, 0, 16, 8, num); \
|
||||
_GST_PUT (data, 1, 16, 0, num); \
|
||||
gpointer __put_data = data; \
|
||||
_GST_PUT (__put_data, 0, 16, 8, num); \
|
||||
_GST_PUT (__put_data, 1, 16, 0, num); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
|
@ -376,8 +383,9 @@ static inline guint64 __gst_fast_read_swap64(const guint8 *v) {
|
|||
* Store a 16 bit unsigned integer value in little endian format into the memory buffer.
|
||||
*/
|
||||
#define GST_WRITE_UINT16_LE(data, num) do { \
|
||||
_GST_PUT (data, 0, 16, 0, num); \
|
||||
_GST_PUT (data, 1, 16, 8, num); \
|
||||
gpointer __put_data = data; \
|
||||
_GST_PUT (__put_data, 0, 16, 0, num); \
|
||||
_GST_PUT (__put_data, 1, 16, 8, num); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
|
|
|
@ -1224,10 +1224,86 @@ GST_START_TEST (test_read_macros)
|
|||
0x4142434445464748);
|
||||
fail_unless_equals_int64_hex (GST_READ_UINT64_LE (uarray),
|
||||
0x4847464544434241);
|
||||
|
||||
/* make sure the data argument is not duplicated inside the macro
|
||||
* with possibly unexpected side-effects */
|
||||
cpointer = carray;
|
||||
fail_unless_equals_int (GST_READ_UINT8 (cpointer++), 'A');
|
||||
fail_unless (cpointer == carray + 1);
|
||||
|
||||
cpointer = carray;
|
||||
fail_unless_equals_int_hex (GST_READ_UINT16_BE (cpointer++), 0x4142);
|
||||
fail_unless (cpointer == carray + 1);
|
||||
|
||||
cpointer = carray;
|
||||
fail_unless_equals_int_hex (GST_READ_UINT32_BE (cpointer++), 0x41424344);
|
||||
fail_unless (cpointer == carray + 1);
|
||||
|
||||
cpointer = carray;
|
||||
fail_unless_equals_int64_hex (GST_READ_UINT64_BE (cpointer++),
|
||||
0x4142434445464748);
|
||||
fail_unless (cpointer == carray + 1);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_write_macros)
|
||||
{
|
||||
guint8 carray[8];
|
||||
guint8 *cpointer;
|
||||
|
||||
/* make sure the data argument is not duplicated inside the macro
|
||||
* with possibly unexpected side-effects */
|
||||
memset (carray, 0, sizeof (carray));
|
||||
cpointer = carray;
|
||||
GST_WRITE_UINT8 (cpointer++, 'A');
|
||||
fail_unless_equals_pointer (cpointer, carray + 1);
|
||||
fail_unless_equals_int (carray[0], 'A');
|
||||
|
||||
memset (carray, 0, sizeof (carray));
|
||||
cpointer = carray;
|
||||
GST_WRITE_UINT16_BE (cpointer++, 0x4142);
|
||||
fail_unless_equals_pointer (cpointer, carray + 1);
|
||||
fail_unless_equals_int (carray[0], 'A');
|
||||
fail_unless_equals_int (carray[1], 'B');
|
||||
|
||||
memset (carray, 0, sizeof (carray));
|
||||
cpointer = carray;
|
||||
GST_WRITE_UINT32_BE (cpointer++, 0x41424344);
|
||||
fail_unless_equals_pointer (cpointer, carray + 1);
|
||||
fail_unless_equals_int (carray[0], 'A');
|
||||
fail_unless_equals_int (carray[3], 'D');
|
||||
|
||||
memset (carray, 0, sizeof (carray));
|
||||
cpointer = carray;
|
||||
GST_WRITE_UINT64_BE (cpointer++, 0x4142434445464748);
|
||||
fail_unless_equals_pointer (cpointer, carray + 1);
|
||||
fail_unless_equals_int (carray[0], 'A');
|
||||
fail_unless_equals_int (carray[7], 'H');
|
||||
|
||||
memset (carray, 0, sizeof (carray));
|
||||
cpointer = carray;
|
||||
GST_WRITE_UINT16_LE (cpointer++, 0x4142);
|
||||
fail_unless_equals_pointer (cpointer, carray + 1);
|
||||
fail_unless_equals_int (carray[0], 'B');
|
||||
fail_unless_equals_int (carray[1], 'A');
|
||||
|
||||
memset (carray, 0, sizeof (carray));
|
||||
cpointer = carray;
|
||||
GST_WRITE_UINT32_LE (cpointer++, 0x41424344);
|
||||
fail_unless_equals_pointer (cpointer, carray + 1);
|
||||
fail_unless_equals_int (carray[0], 'D');
|
||||
fail_unless_equals_int (carray[3], 'A');
|
||||
|
||||
memset (carray, 0, sizeof (carray));
|
||||
cpointer = carray;
|
||||
GST_WRITE_UINT64_LE (cpointer++, 0x4142434445464748);
|
||||
fail_unless_equals_pointer (cpointer, carray + 1);
|
||||
fail_unless_equals_int (carray[0], 'H');
|
||||
fail_unless_equals_int (carray[7], 'A');
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
static Suite *
|
||||
gst_utils_suite (void)
|
||||
{
|
||||
|
@ -1263,6 +1339,7 @@ gst_utils_suite (void)
|
|||
tcase_add_test (tc_chain, test_greatest_common_divisor);
|
||||
|
||||
tcase_add_test (tc_chain, test_read_macros);
|
||||
tcase_add_test (tc_chain, test_write_macros);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue