mirror of
https://github.com/NixOS/nix
synced 2025-06-24 22:11:15 +02:00
libexpr: Switch builtins.sort primop to use peeksort
This prevents C++ level undefined behavior from affecting the evaluator. Stdlib implementation details should not affect eval, regardless of the build platform. Even erroneous usage of `builtins.sort` should not make it possible to crash the evaluator or produce results that depend on the host platform.
This commit is contained in:
parent
b2596a7615
commit
351d898c43
1 changed files with 9 additions and 4 deletions
|
@ -14,6 +14,7 @@
|
||||||
#include "nix/expr/value-to-xml.hh"
|
#include "nix/expr/value-to-xml.hh"
|
||||||
#include "nix/expr/primops.hh"
|
#include "nix/expr/primops.hh"
|
||||||
#include "nix/fetchers/fetch-to-store.hh"
|
#include "nix/fetchers/fetch-to-store.hh"
|
||||||
|
#include "nix/util/sort.hh"
|
||||||
|
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
@ -3695,10 +3696,14 @@ static void prim_sort(EvalState & state, const PosIdx pos, Value * * args, Value
|
||||||
return state.forceBool(vBool, pos, "while evaluating the return value of the sorting function passed to builtins.sort");
|
return state.forceBool(vBool, pos, "while evaluating the return value of the sorting function passed to builtins.sort");
|
||||||
};
|
};
|
||||||
|
|
||||||
/* FIXME: std::sort can segfault if the comparator is not a strict
|
/* NOTE: Using custom implementation because std::sort and std::stable_sort
|
||||||
weak ordering. What to do? std::stable_sort() seems more
|
are not resilient to comparators that violate strict weak ordering. Diagnosing
|
||||||
resilient, but no guarantees... */
|
incorrect implementations is a O(n^3) problem, so doing the checks is much more
|
||||||
std::stable_sort(list.begin(), list.end(), comparator);
|
expensive that doing the sorting. For this reason we choose to use sorting algorithms
|
||||||
|
that are can't be broken by invalid comprators. peeksort (mergesort)
|
||||||
|
doesn't misbehave when any of the strict weak order properties is
|
||||||
|
violated - output is always a reordering of the input. */
|
||||||
|
peeksort(list.begin(), list.end(), comparator);
|
||||||
|
|
||||||
v.mkList(list);
|
v.mkList(list);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue