File chromium-103-SubstringSetMatcher-packed.patch of Package chromium-ffmpeg-extra (Revision acf13cd4d3b182c723d1231bb1ce7ca6)

Currently displaying revision acf13cd4d3b182c723d1231bb1ce7ca6 , Show latest

71
 
1
From 3d274856e792a361336eb4ae1670bc9c1905f0cb Mon Sep 17 00:00:00 2001
2
From: Steinar H. Gunderson <sesse@chromium.org>
3
Date: Thu, 12 May 2022 16:42:40 +0200
4
Subject: [PATCH] Make AhoCorasickNode 4-aligned.
5
6
This should fix an issue where std::vector could allocate unaligned
7
memory for AhoCorasickNode, and we'd then return a pointer to
8
inline_edges, where a caller would expect the pointer to be aligned
9
but it wasn't.
10
11
Change-Id: Id9dff044c61f8e46062c63b8480b18ebc68c4862
12
---
13
14
diff --git a/base/substring_set_matcher/substring_set_matcher.cc b/base/substring_set_matcher/substring_set_matcher.cc
15
index e110047..ef0b750 100644
16
--- a/base/substring_set_matcher/substring_set_matcher.cc
17
+++ b/base/substring_set_matcher/substring_set_matcher.cc
18
@@ -424,7 +424,12 @@
19
     edges_.inline_edges[num_edges()] = AhoCorasickEdge{label, node};
20
     if (label == kFailureNodeLabel) {
21
       // Make sure that kFailureNodeLabel is first.
22
-      std::swap(edges_.inline_edges[0], edges_.inline_edges[num_edges()]);
23
+      // NOTE: We don't use std::swap here, because GCC
24
+      // doesn't understand that inline_edges[] is 4-aligned
25
+      // and gives a warning.
26
+      AhoCorasickEdge temp = edges_.inline_edges[0];
27
+      edges_.inline_edges[0] = edges_.inline_edges[num_edges()];
28
+      edges_.inline_edges[num_edges()] = temp;
29
     }
30
     --num_free_edges_;
31
     return;
32
diff --git a/base/substring_set_matcher/substring_set_matcher.cc b/base/substring_set_matcher/substring_set_matcher.cc
33
index e110047..ef0b750 100644
34
--- a/base/substring_set_matcher/substring_set_matcher.h
35
+++ b/base/substring_set_matcher/substring_set_matcher.h
36
@@ -154,8 +154,9 @@
37
   static constexpr uint32_t kEmptyLabel = 0x103;
38
 
39
   // A node in the trie, packed tightly together so that it occupies 12 bytes
40
-  // (both on 32- and 64-bit platforms).
41
-  class AhoCorasickNode {
42
+  // (both on 32- and 64-bit platforms), but aligned to at least 4 (see the
43
+  // comment on edges_).
44
+  class alignas(AhoCorasickEdge) AhoCorasickNode {
45
    public:
46
     AhoCorasickNode();
47
     ~AhoCorasickNode();
48
@@ -178,6 +179,10 @@
49
     NodeID GetEdgeNoInline(uint32_t label) const;
50
     void SetEdge(uint32_t label, NodeID node);
51
     const AhoCorasickEdge* edges() const {
52
+      // NOTE: Returning edges_.inline_edges here is fine, because it's
53
+      // the first thing in the struct (see the comment on edges_).
54
+      DCHECK_EQ(0u, reinterpret_cast<uintptr_t>(edges_.inline_edges) %
55
+                        alignof(AhoCorasickEdge));
56
       return edges_capacity_ == 0 ? edges_.inline_edges : edges_.edges;
57
     }
58
 
59
@@ -258,6 +263,11 @@
60
     // in the first slot if it exists (ie., is not equal to kRootID), since we
61
     // need to access that label during every single node we look at during
62
     // traversal.
63
+    //
64
+    // NOTE: Keep this the first member in the struct, so that inline_edges gets
65
+    // 4-aligned (since the class is marked as such, despite being packed.
66
+    // Otherwise, edges() can return an unaligned pointer marked as aligned
67
+    // (the unalignedness gets lost).
68
     static constexpr int kNumInlineEdges = 2;
69
     union {
70
       // Out-of-line edge storage, having room for edges_capacity_ elements.
71