|
| 1 | +From: Peter Zhu < [email protected]> |
| 2 | +Date: Thu, 5 Jan 2023 08:48:19 -0500 |
| 3 | +Subject: Fix undefined behavior in shape.c |
| 4 | + |
| 5 | +Under strict aliasing, writing to the memory location of a different |
| 6 | +type is not allowed and will result in undefined behavior. This was |
| 7 | +happening in shape.c due to `rb_id_table_lookup` writing to the memory |
| 8 | +location of `VALUE *` that was casted from a `rb_shape_t **`. |
| 9 | + |
| 10 | +This was causing test failures when compiled with LTO. |
| 11 | + |
| 12 | +Fixes [Bug #19248] |
| 13 | + |
| 14 | +Co-Authored-By: Alan Wu < [email protected]> |
| 15 | +--- |
| 16 | + shape.c | 13 +++++++++++-- |
| 17 | + 1 file changed, 11 insertions(+), 2 deletions(-) |
| 18 | + |
| 19 | +diff --git a/shape.c b/shape.c |
| 20 | +index 7580003..f315012 100644 |
| 21 | +--- a/shape.c |
| 22 | ++++ b/shape.c |
| 23 | +@@ -150,7 +150,11 @@ get_next_shape_internal(rb_shape_t * shape, ID id, enum shape_type shape_type, b |
| 24 | + |
| 25 | + // Lookup the shape in edges - if there's already an edge and a corresponding shape for it, |
| 26 | + // we can return that. Otherwise, we'll need to get a new shape |
| 27 | +- if (!rb_id_table_lookup(shape->edges, id, (VALUE *)&res)) { |
| 28 | ++ VALUE lookup_result; |
| 29 | ++ if (rb_id_table_lookup(shape->edges, id, &lookup_result)) { |
| 30 | ++ res = (rb_shape_t *)lookup_result; |
| 31 | ++ } |
| 32 | ++ else { |
| 33 | + *variation_created = had_edges; |
| 34 | + |
| 35 | + rb_shape_t * new_shape = rb_shape_alloc(id, shape); |
| 36 | +@@ -462,7 +466,12 @@ rb_shape_traverse_from_new_root(rb_shape_t *initial_shape, rb_shape_t *dest_shap |
| 37 | + if (!next_shape->edges) { |
| 38 | + return NULL; |
| 39 | + } |
| 40 | +- if (!rb_id_table_lookup(next_shape->edges, dest_shape->edge_name, (VALUE *)&next_shape)) { |
| 41 | ++ |
| 42 | ++ VALUE lookup_result; |
| 43 | ++ if (rb_id_table_lookup(next_shape->edges, dest_shape->edge_name, &lookup_result)) { |
| 44 | ++ next_shape = (rb_shape_t *)lookup_result; |
| 45 | ++ } |
| 46 | ++ else { |
| 47 | + return NULL; |
| 48 | + } |
| 49 | + break; |
0 commit comments