summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2017-10-07 10:22:50 +0800
committerMaxime Coste <mawww@kakoune.org>2017-11-01 14:05:14 +0800
commitc375268c2d3493d4dc51699eef783c406c167b93 (patch)
treebe3eaf01f0a49ce1140693969b08444a8f29ac5e /src
parentb53227d62c4f490b06457c194c481d744b6add78 (diff)
Regex: Use memcpy to write/read offsets from bytecode
reinterpret_cast was undefined behaviour as we do not guarantee that offsets are going to be stored properly aligned.
Diffstat (limited to 'src')
-rw-r--r--src/regex_impl.cc12
-rw-r--r--src/regex_impl.hh15
2 files changed, 18 insertions, 9 deletions
diff --git a/src/regex_impl.cc b/src/regex_impl.cc
index eacbc1a6..66426aae 100644
--- a/src/regex_impl.cc
+++ b/src/regex_impl.cc
@@ -566,7 +566,7 @@ private:
goto_inner_end_offsets.push_back(alloc_offset());
auto right_pos = compile_node(children[1]);
- get_offset(offset) = right_pos;
+ set_offset(offset, right_pos);
break;
}
@@ -611,7 +611,7 @@ private:
}
for (auto& offset : goto_inner_end_offsets)
- get_offset(offset) = m_program.bytecode.size();
+ set_offset(offset, m_program.bytecode.size());
if (capture != -1)
{
@@ -645,7 +645,7 @@ private:
{
push_op(quantifier.greedy ? CompiledRegex::Split_PrioritizeChild
: CompiledRegex::Split_PrioritizeParent);
- get_offset(alloc_offset()) = inner_pos;
+ set_offset(alloc_offset(), inner_pos);
}
// Write the node as an optional match for the min -> max counts
else for (int i = std::max(1, quantifier.min); // STILL UGLY !
@@ -658,7 +658,7 @@ private:
}
for (auto offset : goto_end_offsets)
- get_offset(offset) = m_program.bytecode.size();
+ set_offset(offset, m_program.bytecode.size());
return pos;
}
@@ -670,9 +670,9 @@ private:
return pos;
}
- Offset& get_offset(Offset pos)
+ void set_offset(Offset pos, Offset value)
{
- return *reinterpret_cast<Offset*>(&m_program.bytecode[pos]);
+ memcpy(&m_program.bytecode[pos], &value, sizeof(Offset));
}
void push_op(CompiledRegex::Op op)
diff --git a/src/regex_impl.hh b/src/regex_impl.hh
index 84b90fa7..0cc1d23f 100644
--- a/src/regex_impl.hh
+++ b/src/regex_impl.hh
@@ -8,6 +8,8 @@
#include "flags.hh"
#include "ref_ptr.hh"
+#include <string.h>
+
namespace Kakoune
{
@@ -199,12 +201,12 @@ private:
case CompiledRegex::AnyChar:
return StepResult::Consumed;
case CompiledRegex::Jump:
- thread.inst = prog_start + *reinterpret_cast<const CompiledRegex::Offset*>(thread.inst);
+ thread.inst = prog_start + get_offset(thread.inst);
break;
case CompiledRegex::Split_PrioritizeParent:
{
auto parent = thread.inst + sizeof(CompiledRegex::Offset);
- auto child = prog_start + *reinterpret_cast<const CompiledRegex::Offset*>(thread.inst);
+ auto child = prog_start + get_offset(thread.inst);
thread.inst = parent;
if (thread.saves)
++thread.saves->refcount;
@@ -214,7 +216,7 @@ private:
case CompiledRegex::Split_PrioritizeChild:
{
auto parent = thread.inst + sizeof(CompiledRegex::Offset);
- auto child = prog_start + *reinterpret_cast<const CompiledRegex::Offset*>(thread.inst);
+ auto child = prog_start + get_offset(thread.inst);
thread.inst = child;
if (thread.saves)
++thread.saves->refcount;
@@ -373,6 +375,13 @@ private:
++start;
}
+ static CompiledRegex::Offset get_offset(const char* ptr)
+ {
+ CompiledRegex::Offset res;
+ memcpy(&res, ptr, sizeof(CompiledRegex::Offset));
+ return res;
+ }
+
bool is_line_start(const Utf8It& pos) const
{
return (pos == m_begin and not (m_flags & RegexExecFlags::NotBeginOfLine)) or