From 6d965bf6c151a45d71b087a1b12482213f3493bd Mon Sep 17 00:00:00 2001 From: Demi Marie Obenour Date: Sat, 3 Jun 2023 18:39:05 -0400 Subject: [PATCH] tmp --- src/c_client.py | 52 +++++++++++++++++++++++++++++++++++++------------ src/xcb_conn.c | 38 ++++++++++++++++++++++-------------- 2 files changed, 63 insertions(+), 27 deletions(-) diff --git a/src/c_client.py b/src/c_client.py index a80d4ba..85d15cf 100644 --- a/src/c_client.py +++ b/src/c_client.py @@ -881,7 +881,7 @@ def _c_serialize_helper_switch(context, self, complex_name, code_lines, temp_vars, space, prefix): count = 0 - switch_expr = _c_accessor_get_expr(self.expr, None, False) + switch_expr = _c_accessor_get_expr(self.expr, None, context.endswith('checked')) for b in self.bitcases: len_expr = len(b.type.expr) @@ -893,7 +893,7 @@ def _c_serialize_helper_switch(context, self, complex_name, compare_operator = '&' for n, expr in enumerate(b.type.expr): - bitcase_expr = _c_accessor_get_expr(expr, None, False) + bitcase_expr = _c_accessor_get_expr(expr, None, context.endswith('checked')) # only one in the if len_expr == 1: code_lines.append( @@ -1029,7 +1029,7 @@ def _c_serialize_helper_list_field(context, self, field, if expr.op == 'calculate_len': list_length = field.type.expr.lenfield_name else: - list_length = _c_accessor_get_expr(expr, field_mapping, False) + list_length = _c_accessor_get_expr(expr, field_mapping, context.endswith('checked')) # default: list with fixed size elements length = 'xcb_checked_mul(%s, sizeof(%s))' % (list_length, field.type.member.c_wiretype) @@ -1367,7 +1367,7 @@ def _c_serialize_helper(context, complex_type, count += _c_serialize_helper_fields(context, self, code_lines, temp_vars, - space, prefix, False) + space, prefix, context.endswith('checked')) # "final padding" count += _c_serialize_helper_insert_padding(context, complex_type, code_lines, space, False, self.is_switch) @@ -1743,7 +1743,6 @@ def _c_accessor_get_expr(expr, field_mapping, checked): Otherwise, uses the value of the length field. ''' lenexp = _c_accessor_get_length(expr, field_mapping) - if expr.op == '~': # SAFE return '(' + '~' + _c_accessor_get_expr(expr.rhs, field_mapping, checked) + ')' elif expr.op == 'popcount': # SAFE @@ -1822,9 +1821,39 @@ def _c_accessor_get_expr(expr, field_mapping, checked): elif expr.op == 'listelement-ref': return '(*xcb_listelement)' elif expr.op != None and expr.op != 'calculate_len': - return ('(' + _c_accessor_get_expr(expr.lhs, field_mapping, checked) + - ' ' + expr.op + ' ' + - _c_accessor_get_expr(expr.rhs, field_mapping, checked) + ')') + _c_pre.start() + sumvar = _c_pre.get_tempvarname() + match expr.op: + case '+': + op = 'add' + case '-': + op = 'sub' + case '*': + op = 'mul' + case '/': + _c_pre.tempvar("int64_t %s;", sumvar) + _c_pre.code("%s = (%s);", + sumvar, + _c_accessor_get_expr(expr.rhs, field_mapping, checked)) + _c_pre.code("if (%s < 1)", sumvar) + _c_pre.code(" return -1;" if checked else " abort();") + _c_pre.end() + return ('((' + _c_accessor_get_expr(expr.lhs, field_mapping, checked) + ') / ' + sumvar + ')') + case '&': + _c_pre.end() + return ('(' + _c_accessor_get_expr(expr.lhs, field_mapping, checked) + + ' & ' + _c_accessor_get_expr(expr.rhs, field_mapping, checked) + ')') + case _: + assert False + _c_pre.tempvar("int64_t %s; /* sum */", sumvar) + _c_pre.code("if (__builtin_%s_overflow((%s), (%s), &%s))", + op, + _c_accessor_get_expr(expr.lhs, field_mapping, checked), + _c_accessor_get_expr(expr.rhs, field_mapping, checked), + sumvar) + _c_pre.code(" return -1;" if checked else " abort();") + _c_pre.end() + return ('(' + sumvar + ')') elif expr.bitfield: return 'xcb_popcount(' + lenexp + ')' else: @@ -2137,10 +2166,9 @@ def _c_accessors(self, name, base): ''' # no accessors for switch itself - # switch always needs to be unpacked explicitly -# if self.is_switch: -# pass -# else: - if True: + if self.is_switch: + assert False + else: for field in self.fields: if not field.type.is_pad: if _c_field_needs_list_accessor(field): diff --git a/src/xcb_conn.c b/src/xcb_conn.c index 61b8a9c..a467baa 100644 --- a/src/xcb_conn.c +++ b/src/xcb_conn.c @@ -30,9 +30,7 @@ #endif #include -#if __STDC_VERSION__ >= 201112L #include -#endif #include #include #include @@ -241,12 +239,16 @@ static int read_setup(xcb_connection_t *c) * Padded length of the vendor string. setup->vendor_len is a * uint16_t so overflow is impossible. Cannot exceed 65536. */ + static_assert(sizeof(setup->vendor_len) == 2, + "wrong size of setup->vendor_len"); uint32_t const pixmap_offset = (setup->vendor_len + UINT32_C(3)) & ~UINT32_C(3); /* * Length of the pixmap formats. setup->pixmap_formats_len is * uint8_t so overflow is impossible. */ + static_assert(sizeof(setup->pixmap_formats_len) == 1, + "wrong size of setup->pixmap_formats_len"); uint32_t const pixmap_formats_len = sizeof(xcb_format_t) * setup->pixmap_formats_len; /* Offset of the screens. Max RHS = 40 + 65536 + 8 * 255 = 67616 so no risk of overflow */ @@ -255,20 +257,24 @@ static int read_setup(xcb_connection_t *c) /* 4 zero bytes, for memcmp() */ uint32_t const zero = 0; -#if __STDC_VERSION__ >= 201112L /* A bunch of static assertions */ - static_assert(sizeof(xcb_screen_t) == 40, "bug"); - static_assert(sizeof(xcb_setup_t) == 40, "bug"); - static_assert(sizeof(xcb_setup_generic_t) == 8, "bug"); - static_assert(sizeof(xcb_setup_authenticate_t) == 8, "bug"); - static_assert(sizeof(xcb_setup_failed_t) == 8, "bug"); - static_assert(sizeof(xcb_visualtype_t) == 24, "bug"); - static_assert(sizeof(xcb_depth_t) == 8, "bug"); - static_assert(sizeof(xcb_format_t) == 8, "bug"); - static_assert(alignof(xcb_screen_t) == 4, "bug"); - static_assert(alignof(xcb_visualtype_t) == 4, "bug"); - static_assert(alignof(xcb_depth_t) == 2, "bug"); -#endif +#define ASSERT_SIZE_ALIGN(t, size, align) \ + do { \ + static_assert(sizeof(t) == size, \ + "unexpected size of" #t); \ + static_assert(alignof(t) == align, \ + "unexpected alignment of" #t); \ + } while (0); + ASSERT_SIZE_ALIGN(xcb_screen_t, 40, 4); + ASSERT_SIZE_ALIGN(xcb_setup_t, 40, 4); + ASSERT_SIZE_ALIGN(xcb_setup_generic_t, 8, 2); + ASSERT_SIZE_ALIGN(xcb_setup_authenticate_t, 8, 2); + ASSERT_SIZE_ALIGN(xcb_setup_failed_t, 8, 2); + ASSERT_SIZE_ALIGN(xcb_visualtype_t, 24, 4); + ASSERT_SIZE_ALIGN(xcb_depth_t, 8, 2); + ASSERT_SIZE_ALIGN(xcb_format_t, 8, 1); +#undef ASSERT_SIZE_ALIGN + /* Must have at least 1 screen and 1 pixmap format */ if (setup->roots_len < 1 || setup->pixmap_formats_len < 1) return 0; @@ -348,6 +354,8 @@ static int read_setup(xcb_connection_t *c) return 0; /* depth->visuals_len is uint16_t so overflow is impossible. */ + static_assert(sizeof(depth->visuals_len) == 2, + "wrong size of setup->visuals_len"); visuals_size = (uint32_t)depth->visuals_len * sizeof(*visuals); /* Visuals must fit in the buffer. */