diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index d408f1adcc87..ea1bf88eb8e5 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -957,6 +957,15 @@ void Value::mkString(std::string_view s, const NixStringContext & context) copyContextToValue(*this, context); } +void Value::mkEmptyString(const Value & other) +{ + mkString(""); + + NixStringContext context; + copyContext(other, context); + copyContextToValue(*this, context); +} + void Value::mkStringMove(const char * s, const NixStringContext & context) { mkString(s); diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 85360f0f9f25..3e9816b1955c 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -3724,10 +3724,10 @@ static void prim_substring(EvalState & state, const PosIdx pos, Value * * args, // Special-case on empty substring to avoid O(n) strlen // This allows for the use of empty substrings to efficently capture string context - if (len <= 0) { + if (len == 0) { state.forceValue(*args[2], pos); if (args[2]->type() == nString) { - v.mkString("", args[2]->string.context); + v.mkEmptyString(*args[2]); return; } } diff --git a/src/libexpr/tests/libnixexpr-tests b/src/libexpr/tests/libnixexpr-tests new file mode 100755 index 000000000000..f81c43bf6dd2 Binary files /dev/null and b/src/libexpr/tests/libnixexpr-tests differ diff --git a/src/libexpr/value.hh b/src/libexpr/value.hh index c65b336b0aa4..06f9d316f368 100644 --- a/src/libexpr/value.hh +++ b/src/libexpr/value.hh @@ -293,6 +293,8 @@ public: void mkStringMove(const char * s, const NixStringContext & context); + void mkEmptyString(const Value & other); + inline void mkString(const Symbol & s) { mkString(((const std::string &) s).c_str()); diff --git a/src/libstore/tests/libnixstore-tests b/src/libstore/tests/libnixstore-tests new file mode 100755 index 000000000000..50122dc30e8b Binary files /dev/null and b/src/libstore/tests/libnixstore-tests differ diff --git a/src/libutil/tests/libnixutil-tests b/src/libutil/tests/libnixutil-tests new file mode 100755 index 000000000000..67934e3dce2d Binary files /dev/null and b/src/libutil/tests/libnixutil-tests differ