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
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
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
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
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