diff options
author | eldritch horrors <pennae@lix.systems> | 2024-01-29 06:19:23 +0100 |
---|---|---|
committer | eldritch horrors <pennae@lix.systems> | 2024-03-18 07:56:23 -0600 |
commit | 314f044c2bbb8dd8799df6c76f6d81109bf35043 (patch) | |
tree | 8ebe20a878cdd7ffe295973ab0c6a6e779bd60e6 /src/libexpr/eval.cc | |
parent | 1f8b85786eed623319e5c71a5341b15e3006f870 (diff) |
keep copies of parser inputs that are in-memory only
the parser modifies its inputs, which means that sharing them between
the error context reporting system and the parser itself can confuse the
reporting system. usually this led to early truncation of error context
reports which, while not dangerous, can be quite confusing.
(cherry picked from commit d384ecd553aa997270b79ee98d02f7cf7e1849e6)
Change-Id: I677646b5675b12b2faa787943646aa36dc6e6ee3
Diffstat (limited to 'src/libexpr/eval.cc')
-rw-r--r-- | src/libexpr/eval.cc | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 1739a04fa..32766950d 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -2745,9 +2745,12 @@ Expr * EvalState::parseExprFromFile(const SourcePath & path, std::shared_ptr<Sta Expr * EvalState::parseExprFromString(std::string s_, const SourcePath & basePath, std::shared_ptr<StaticEnv> & staticEnv) { - auto s = make_ref<std::string>(std::move(s_)); - s->append("\0\0", 2); - return parse(s->data(), s->size(), Pos::String{.source = s}, basePath, staticEnv); + // NOTE this method (and parseStdin) must take care to *fully copy* their input + // into their respective Pos::Origin until the parser stops overwriting its input + // data. + auto s = make_ref<std::string>(s_); + s_.append("\0\0", 2); + return parse(s_.data(), s_.size(), Pos::String{.source = s}, basePath, staticEnv); } @@ -2759,12 +2762,15 @@ Expr * EvalState::parseExprFromString(std::string s, const SourcePath & basePath Expr * EvalState::parseStdin() { + // NOTE this method (and parseExprFromString) must take care to *fully copy* their + // input into their respective Pos::Origin until the parser stops overwriting its + // input data. //Activity act(*logger, lvlTalkative, "parsing standard input"); auto buffer = drainFD(0); // drainFD should have left some extra space for terminators + auto s = make_ref<std::string>(buffer); buffer.append("\0\0", 2); - auto s = make_ref<std::string>(std::move(buffer)); - return parse(s->data(), s->size(), Pos::Stdin{.source = s}, rootPath(CanonPath::fromCwd()), staticBaseEnv); + return parse(buffer.data(), buffer.size(), Pos::Stdin{.source = s}, rootPath(CanonPath::fromCwd()), staticBaseEnv); } |