boostorg / boostorg/parser

Sequence parser overwrites std::u32string

Open
#327 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
182
Forks
28
PR merge metrics
No merged PRs in 30d

Description

Consider the following example.
```cpp
#include
#include

#include

namespace bp = boost::parser;

int main(int argc, char *argv[]) {
auto input = std::string{"ab"};
auto res = std::string();
const auto result = bp::parse(
input
, (bp::char_ >> bp::char_)
, res
);
if (result) {
std::print("Parse successful\n");
std::print("{}\n", res);
} else {
std::print("Parse failed\n");
}
}
```
It outputs
```
Parse successful
ab
```
Now consider this change
```cpp
#include
#include
#include

#include
#include

namespace bp = boost::parser;
namespace rs = std::ranges;

int main(int argc, char *argv[]) {
auto input = std::u32string{U"ab"};
auto res = std::u32string();
const auto result = bp::parse(
input
, (bp::char_ >> bp::char_)
, res
);
if (result) {
std::print("Parse successful\n");
std::print("{}\n", res | bp::as_utf8 | rs::to());
} else {
std::print("Parse failed\n");
}
}
```
It outputs
```
Parse successful
b
```
The issue is here:
```cpp
if constexpr (detail::is_nope_v) {
// nothing to do
} if constexpr (
(!out_container ||
!std::is_same_v) &&
std::is_assignable_v &&
(!std::is_same_v ||
!std::is_integral_v)) {
detail::assign(out, std::move(x));
} else {
detail::move_back(
out, std::move(x), detail::gen_attrs(flags));
}
```
This code adds to a string only if it is an `std::string`. Otherwise, it assigns every character to the same string.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.