mirror of
https://github.com/NixOS/nix
synced 2025-07-02 13:31:48 +02:00
Merge remote-tracking branch 'upstream/master' into lfs
This commit is contained in:
commit
b08b7bee4e
101 changed files with 2148 additions and 395 deletions
|
@ -3185,12 +3185,16 @@ std::ostream & operator << (std::ostream & str, const ExternalValueBase & v) {
|
|||
return v.print(str);
|
||||
}
|
||||
|
||||
void forceNoNullByte(std::string_view s)
|
||||
void forceNoNullByte(std::string_view s, std::function<Pos()> pos)
|
||||
{
|
||||
if (s.find('\0') != s.npos) {
|
||||
using namespace std::string_view_literals;
|
||||
auto str = replaceStrings(std::string(s), "\0"sv, "␀"sv);
|
||||
throw Error("input string '%s' cannot be represented as Nix string because it contains null bytes", str);
|
||||
Error error("input string '%s' cannot be represented as Nix string because it contains null bytes", str);
|
||||
if (pos) {
|
||||
error.atPos(pos());
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,16 +41,18 @@ namespace nix {
|
|||
|
||||
// we make use of the fact that the parser receives a private copy of the input
|
||||
// string and can munge around in it.
|
||||
static StringToken unescapeStr(SymbolTable & symbols, char * s, size_t length)
|
||||
// getting the position is expensive and thus it is implemented lazily.
|
||||
static StringToken unescapeStr(char * const s, size_t length, std::function<Pos()> && pos)
|
||||
{
|
||||
char * result = s;
|
||||
bool noNullByte = true;
|
||||
char * t = s;
|
||||
char c;
|
||||
// the input string is terminated with *two* NULs, so we can safely take
|
||||
// *one* character after the one being checked against.
|
||||
while ((c = *s++)) {
|
||||
for (size_t i = 0; i < length; t++) {
|
||||
char c = s[i++];
|
||||
noNullByte &= c != '\0';
|
||||
if (c == '\\') {
|
||||
c = *s++;
|
||||
c = s[i++];
|
||||
if (c == 'n') *t = '\n';
|
||||
else if (c == 'r') *t = '\r';
|
||||
else if (c == 't') *t = '\t';
|
||||
|
@ -59,12 +61,14 @@ static StringToken unescapeStr(SymbolTable & symbols, char * s, size_t length)
|
|||
else if (c == '\r') {
|
||||
/* Normalise CR and CR/LF into LF. */
|
||||
*t = '\n';
|
||||
if (*s == '\n') s++; /* cr/lf */
|
||||
if (s[i] == '\n') i++; /* cr/lf */
|
||||
}
|
||||
else *t = c;
|
||||
t++;
|
||||
}
|
||||
return {result, size_t(t - result)};
|
||||
if (!noNullByte) {
|
||||
forceNoNullByte({s, size_t(t - s)}, std::move(pos));
|
||||
}
|
||||
return {s, size_t(t - s)};
|
||||
}
|
||||
|
||||
static void requireExperimentalFeature(const ExperimentalFeature & feature, const Pos & pos)
|
||||
|
@ -175,7 +179,7 @@ or { return OR_KW; }
|
|||
/* It is impossible to match strings ending with '$' with one
|
||||
regex because trailing contexts are only valid at the end
|
||||
of a rule. (A sane but undocumented limitation.) */
|
||||
yylval->str = unescapeStr(state->symbols, yytext, yyleng);
|
||||
yylval->str = unescapeStr(yytext, yyleng, [&]() { return state->positions[CUR_POS]; });
|
||||
return STR;
|
||||
}
|
||||
<STRING>\$\{ { PUSH_STATE(DEFAULT); return DOLLAR_CURLY; }
|
||||
|
@ -191,6 +195,7 @@ or { return OR_KW; }
|
|||
\'\'(\ *\n)? { PUSH_STATE(IND_STRING); return IND_STRING_OPEN; }
|
||||
<IND_STRING>([^\$\']|\$[^\{\']|\'[^\'\$])+ {
|
||||
yylval->str = {yytext, (size_t) yyleng, true};
|
||||
forceNoNullByte(yylval->str, [&]() { return state->positions[CUR_POS]; });
|
||||
return IND_STR;
|
||||
}
|
||||
<IND_STRING>\'\'\$ |
|
||||
|
@ -203,7 +208,7 @@ or { return OR_KW; }
|
|||
return IND_STR;
|
||||
}
|
||||
<IND_STRING>\'\'\\{ANY} {
|
||||
yylval->str = unescapeStr(state->symbols, yytext + 2, yyleng - 2);
|
||||
yylval->str = unescapeStr(yytext + 2, yyleng - 2, [&]() { return state->positions[CUR_POS]; });
|
||||
return IND_STR;
|
||||
}
|
||||
<IND_STRING>\$\{ { PUSH_STATE(DEFAULT); return DOLLAR_CURLY; }
|
||||
|
|
|
@ -4,8 +4,6 @@ project('nix-expr', 'cpp',
|
|||
'cpp_std=c++2a',
|
||||
# TODO(Qyriad): increase the warning level
|
||||
'warning_level=1',
|
||||
'debug=true',
|
||||
'optimization=2',
|
||||
'errorlogs=true', # Please print logs for tests that fail
|
||||
],
|
||||
meson_version : '>= 1.1',
|
||||
|
|
|
@ -2045,7 +2045,7 @@ static RegisterPrimOp primop_readFileType({
|
|||
.args = {"p"},
|
||||
.doc = R"(
|
||||
Determine the directory entry type of a filesystem node, being
|
||||
one of "directory", "regular", "symlink", or "unknown".
|
||||
one of `"directory"`, `"regular"`, `"symlink"`, or `"unknown"`.
|
||||
)",
|
||||
.fun = prim_readFileType,
|
||||
});
|
||||
|
@ -4059,7 +4059,7 @@ static RegisterPrimOp primop_toString({
|
|||
});
|
||||
|
||||
/* `substring start len str' returns the substring of `str' starting
|
||||
at character position `min(start, stringLength str)' inclusive and
|
||||
at byte position `min(start, stringLength str)' inclusive and
|
||||
ending at `min(start + len, stringLength str)'. `start' must be
|
||||
non-negative. */
|
||||
static void prim_substring(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||
|
@ -4098,7 +4098,7 @@ static RegisterPrimOp primop_substring({
|
|||
.name = "__substring",
|
||||
.args = {"start", "len", "s"},
|
||||
.doc = R"(
|
||||
Return the substring of *s* from character position *start*
|
||||
Return the substring of *s* from byte position *start*
|
||||
(zero-based) up to but not including *start + len*. If *start* is
|
||||
greater than the length of the string, an empty string is returned.
|
||||
If *start + len* lies beyond the end of the string or *len* is `-1`,
|
||||
|
|
|
@ -108,7 +108,11 @@ json printValueAsJSON(EvalState & state, bool strict,
|
|||
void printValueAsJSON(EvalState & state, bool strict,
|
||||
Value & v, const PosIdx pos, std::ostream & str, NixStringContext & context, bool copyToStore)
|
||||
{
|
||||
str << printValueAsJSON(state, strict, v, pos, context, copyToStore);
|
||||
try {
|
||||
str << printValueAsJSON(state, strict, v, pos, context, copyToStore);
|
||||
} catch (nlohmann::json::exception & e) {
|
||||
throw JSONSerializationError("JSON serialization error: %s", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
json ExternalValueBase::printValueAsJSON(EvalState & state, bool strict,
|
||||
|
|
|
@ -16,4 +16,7 @@ nlohmann::json printValueAsJSON(EvalState & state, bool strict,
|
|||
void printValueAsJSON(EvalState & state, bool strict,
|
||||
Value & v, const PosIdx pos, std::ostream & str, NixStringContext & context, bool copyToStore = true);
|
||||
|
||||
|
||||
MakeError(JSONSerializationError, Error);
|
||||
|
||||
}
|
||||
|
|
|
@ -510,6 +510,6 @@ typedef std::shared_ptr<Value *> RootValue;
|
|||
|
||||
RootValue allocRootValue(Value * v);
|
||||
|
||||
void forceNoNullByte(std::string_view s);
|
||||
void forceNoNullByte(std::string_view s, std::function<Pos()> = nullptr);
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue