1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-19 00:39:37 +01:00

Use Boost's regex implementation instead of libstdc++'s

The latter runs in unbounded stack space so it crashes on large
inputs.

Fixes #4550.
This commit is contained in:
Eelco Dolstra 2021-02-17 16:13:24 +01:00
parent 6042febfce
commit 23a97b0079
4 changed files with 18 additions and 13 deletions

View file

@ -135,7 +135,7 @@
# Copy libboost_context so we don't get all of Boost in our closure. # Copy libboost_context so we don't get all of Boost in our closure.
# https://github.com/NixOS/nixpkgs/issues/45462 # https://github.com/NixOS/nixpkgs/issues/45462
mkdir -p $out/lib mkdir -p $out/lib
cp -pd ${boost}/lib/{libboost_context*,libboost_thread*,libboost_system*} $out/lib cp -pd ${boost}/lib/{libboost_context*,libboost_thread*,libboost_system*,libboost_regex*} $out/lib
rm -f $out/lib/*.a rm -f $out/lib/*.a
${lib.optionalString stdenv.isLinux '' ${lib.optionalString stdenv.isLinux ''
chmod u+w $out/lib/*.so.* chmod u+w $out/lib/*.so.*

6
src/libutil/regex.hh Normal file
View file

@ -0,0 +1,6 @@
#pragma once
#include <boost/regex.hpp>
namespace regex = boost;

View file

@ -6,8 +6,7 @@
#include "derivations.hh" #include "derivations.hh"
#include "affinity.hh" #include "affinity.hh"
#include "progress-bar.hh" #include "progress-bar.hh"
#include "regex.hh"
#include <regex>
using namespace nix; using namespace nix;
@ -64,42 +63,42 @@ BuildEnvironment readEnvironment(const Path & path)
static std::string indexedArrayRegex = static std::string indexedArrayRegex =
R"re((?:\(( *\[[0-9]+\]="(?:[^"\\]|\\.)*")*\)))re"; R"re((?:\(( *\[[0-9]+\]="(?:[^"\\]|\\.)*")*\)))re";
static std::regex declareRegex( static regex::regex declareRegex(
"^declare -a?x (" + varNameRegex + ")(=(" + "^declare -a?x (" + varNameRegex + ")(=(" +
dquotedStringRegex + "|" + indexedArrayRegex + "))?\n"); dquotedStringRegex + "|" + indexedArrayRegex + "))?\n");
static std::regex varRegex( static regex::regex varRegex(
"^(" + varNameRegex + ")=(" + simpleStringRegex + "|" + squotedStringRegex + "|" + indexedArrayRegex + ")\n"); "^(" + varNameRegex + ")=(" + simpleStringRegex + "|" + squotedStringRegex + "|" + indexedArrayRegex + ")\n");
/* Note: we distinguish between an indexed and associative array /* Note: we distinguish between an indexed and associative array
using the space before the closing parenthesis. Will using the space before the closing parenthesis. Will
undoubtedly regret this some day. */ undoubtedly regret this some day. */
static std::regex assocArrayRegex( static regex::regex assocArrayRegex(
"^(" + varNameRegex + ")=" + R"re((?:\(( *\[[^\]]+\]="(?:[^"\\]|\\.)*")* *\)))re" + "\n"); "^(" + varNameRegex + ")=" + R"re((?:\(( *\[[^\]]+\]="(?:[^"\\]|\\.)*")* *\)))re" + "\n");
static std::regex functionRegex( static regex::regex functionRegex(
"^" + varNameRegex + " \\(\\) *\n"); "^" + varNameRegex + " \\(\\) *\n");
while (pos != file.end()) { while (pos != file.end()) {
std::smatch match; regex::smatch match;
if (std::regex_search(pos, file.cend(), match, declareRegex, std::regex_constants::match_continuous)) { if (regex::regex_search(pos, file.cend(), match, declareRegex, regex::regex_constants::match_continuous)) {
pos = match[0].second; pos = match[0].second;
exported.insert(match[1]); exported.insert(match[1]);
} }
else if (std::regex_search(pos, file.cend(), match, varRegex, std::regex_constants::match_continuous)) { else if (regex::regex_search(pos, file.cend(), match, varRegex, regex::regex_constants::match_continuous)) {
pos = match[0].second; pos = match[0].second;
res.env.insert({match[1], Var { .exported = exported.count(match[1]) > 0, .quoted = match[2] }}); res.env.insert({match[1], Var { .exported = exported.count(match[1]) > 0, .quoted = match[2] }});
} }
else if (std::regex_search(pos, file.cend(), match, assocArrayRegex, std::regex_constants::match_continuous)) { else if (regex::regex_search(pos, file.cend(), match, assocArrayRegex, regex::regex_constants::match_continuous)) {
pos = match[0].second; pos = match[0].second;
res.env.insert({match[1], Var { .associative = true, .quoted = match[2] }}); res.env.insert({match[1], Var { .associative = true, .quoted = match[2] }});
} }
else if (std::regex_search(pos, file.cend(), match, functionRegex, std::regex_constants::match_continuous)) { else if (regex::regex_search(pos, file.cend(), match, functionRegex, regex::regex_constants::match_continuous)) {
res.bashFunctions = std::string(pos, file.cend()); res.bashFunctions = std::string(pos, file.cend());
break; break;
} }

View file

@ -18,7 +18,7 @@ nix_CXXFLAGS += -I src/libutil -I src/libstore -I src/libfetchers -I src/libexpr
nix_LIBS = libexpr libmain libfetchers libstore libutil libcmd nix_LIBS = libexpr libmain libfetchers libstore libutil libcmd
nix_LDFLAGS = -pthread $(SODIUM_LIBS) $(EDITLINE_LIBS) $(BOOST_LDFLAGS) -llowdown nix_LDFLAGS = -pthread $(SODIUM_LIBS) $(EDITLINE_LIBS) $(BOOST_LDFLAGS) -llowdown -lboost_regex
$(foreach name, \ $(foreach name, \
nix-build nix-channel nix-collect-garbage nix-copy-closure nix-daemon nix-env nix-hash nix-instantiate nix-prefetch-url nix-shell nix-store, \ nix-build nix-channel nix-collect-garbage nix-copy-closure nix-daemon nix-env nix-hash nix-instantiate nix-prefetch-url nix-shell nix-store, \