[Xcb] [PATCH libxcb 1/1] Fix for alignment bug when xcb_align_to is 0

Christian Linhart chris at demorecorder.com
Fri Jun 12 02:48:00 PDT 2015


The aligment code in xcb looks like:
    xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
if xcb_align_to == 0, then (xcb_align_to - 1) evaluates to INT_MAX.
This causes alignments which may become too large.

xcb_align_to can become 0 in certain cases.
Actually, it is often initialized to 0.

This patch fixes that by adding an "if" which causes
alignment computations only for xcb_align > 1.
We also exclude 1 because aligment 1 is a NOP.
Therefore this fix improves performance, too.

Thanks to Peter Hutterer for pointing out this problem to me.

BTW, long term we should remove the implicit padding
altogether. This was already consensus on the list,
but it is significant work to ensure correctness.
So it is postponed for now.

Signed-off-by: Christian Linhart <chris at demorecorder.com>
---
 src/c_client.py | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/src/c_client.py b/src/c_client.py
index 70f8429..eca18c8 100644
--- a/src/c_client.py
+++ b/src/c_client.py
@@ -814,22 +814,28 @@ def get_serialize_params(context, self, buffer_var='_buffer', aux_var='_aux'):
             if not p.type.fixed_size():
                 add_param(params, (p.c_field_const_type, '*', p.c_field_name))
 
     return (param_fields, wire_fields, params)
 
 def _c_serialize_helper_insert_padding(context, code_lines, space, postpone, is_case_or_bitcase):
     code_lines.append('%s    /* insert padding */' % space)
+    code_lines.append('%s    if (xcb_align_to > 1) {' % space)
     if is_case_or_bitcase:
         code_lines.append(
-            '%s    xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);'
+            '%s        xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);'
             % space)
     else:
         code_lines.append(
-            '%s    xcb_pad = -xcb_block_len & (xcb_align_to - 1);' % space)
-    code_lines.append('%s    xcb_buffer_len += xcb_block_len + xcb_pad;' % space)
+            '%s        xcb_pad = -xcb_block_len & (xcb_align_to - 1);' % space)
+    code_lines.append('%s        xcb_buffer_len += xcb_block_len + xcb_pad;' % space)
+    code_lines.append('%s    }' % space)
+    code_lines.append('%s    else {' % space)
+    code_lines.append('%s        xcb_pad = 0;' % space)
+    code_lines.append('%s        xcb_buffer_len += xcb_block_len;' % space)
+    code_lines.append('%s    }' % space)
 
     if not postpone:
         code_lines.append('%s    if (0 != xcb_pad) {' % space)
 
         if 'serialize' == context:
             code_lines.append('%s        xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;' % space)
             code_lines.append('%s        xcb_parts[xcb_parts_idx].iov_len = xcb_pad;' % space)
-- 
2.0.1



More information about the Xcb mailing list