toXML: display errors position

- This change applies to builtins.toXML and inner workings
- Proof of concept:
  ```nix
  let e = builtins.toXML e; in e
  ```
- Before:
  ```
  $ nix-instantiate --eval poc.nix
  error: infinite recursion encountered
  ```
- After:
  ```
  $ nix-instantiate --eval poc.nix
  error: infinite recursion encountered

       at /data/github/kamadorueda/nix/poc.nix:1:9:

            1| let e = builtins.toXML e; in e
             |
  ```
This commit is contained in:
Kevin Amado 2021-11-13 20:29:31 -05:00
parent bceda30498
commit d0e9e18489
No known key found for this signature in database
GPG key ID: FFF341057F503148
5 changed files with 20 additions and 16 deletions

View file

@ -1582,7 +1582,7 @@ static void prim_toXML(EvalState & state, const Pos & pos, Value * * args, Value
{ {
std::ostringstream out; std::ostringstream out;
PathSet context; PathSet context;
printValueAsXML(state, true, false, *args[0], out, context); printValueAsXML(state, true, false, *args[0], out, context, pos);
mkString(v, out.str(), context); mkString(v, out.str(), context);
} }

View file

@ -18,7 +18,8 @@ static XMLAttrs singletonAttrs(const string & name, const string & value)
static void printValueAsXML(EvalState & state, bool strict, bool location, static void printValueAsXML(EvalState & state, bool strict, bool location,
Value & v, XMLWriter & doc, PathSet & context, PathSet & drvsSeen); Value & v, XMLWriter & doc, PathSet & context, PathSet & drvsSeen,
const Pos & pos);
static void posToXML(XMLAttrs & xmlAttrs, const Pos & pos) static void posToXML(XMLAttrs & xmlAttrs, const Pos & pos)
@ -46,17 +47,18 @@ static void showAttrs(EvalState & state, bool strict, bool location,
XMLOpenElement _(doc, "attr", xmlAttrs); XMLOpenElement _(doc, "attr", xmlAttrs);
printValueAsXML(state, strict, location, printValueAsXML(state, strict, location,
*a.value, doc, context, drvsSeen); *a.value, doc, context, drvsSeen, *a.pos);
} }
} }
static void printValueAsXML(EvalState & state, bool strict, bool location, static void printValueAsXML(EvalState & state, bool strict, bool location,
Value & v, XMLWriter & doc, PathSet & context, PathSet & drvsSeen) Value & v, XMLWriter & doc, PathSet & context, PathSet & drvsSeen,
const Pos & pos)
{ {
checkInterrupt(); checkInterrupt();
if (strict) state.forceValue(v); if (strict) state.forceValue(v, pos);
switch (v.type()) { switch (v.type()) {
@ -91,14 +93,14 @@ static void printValueAsXML(EvalState & state, bool strict, bool location,
Path drvPath; Path drvPath;
a = v.attrs->find(state.sDrvPath); a = v.attrs->find(state.sDrvPath);
if (a != v.attrs->end()) { if (a != v.attrs->end()) {
if (strict) state.forceValue(*a->value); if (strict) state.forceValue(*a->value, *a->pos);
if (a->value->type() == nString) if (a->value->type() == nString)
xmlAttrs["drvPath"] = drvPath = a->value->string.s; xmlAttrs["drvPath"] = drvPath = a->value->string.s;
} }
a = v.attrs->find(state.sOutPath); a = v.attrs->find(state.sOutPath);
if (a != v.attrs->end()) { if (a != v.attrs->end()) {
if (strict) state.forceValue(*a->value); if (strict) state.forceValue(*a->value, *a->pos);
if (a->value->type() == nString) if (a->value->type() == nString)
xmlAttrs["outPath"] = a->value->string.s; xmlAttrs["outPath"] = a->value->string.s;
} }
@ -121,7 +123,7 @@ static void printValueAsXML(EvalState & state, bool strict, bool location,
case nList: { case nList: {
XMLOpenElement _(doc, "list"); XMLOpenElement _(doc, "list");
for (unsigned int n = 0; n < v.listSize(); ++n) for (unsigned int n = 0; n < v.listSize(); ++n)
printValueAsXML(state, strict, location, *v.listElems()[n], doc, context, drvsSeen); printValueAsXML(state, strict, location, *v.listElems()[n], doc, context, drvsSeen, pos);
break; break;
} }
@ -149,7 +151,7 @@ static void printValueAsXML(EvalState & state, bool strict, bool location,
} }
case nExternal: case nExternal:
v.external->printValueAsXML(state, strict, location, doc, context, drvsSeen); v.external->printValueAsXML(state, strict, location, doc, context, drvsSeen, pos);
break; break;
case nFloat: case nFloat:
@ -163,19 +165,20 @@ static void printValueAsXML(EvalState & state, bool strict, bool location,
void ExternalValueBase::printValueAsXML(EvalState & state, bool strict, void ExternalValueBase::printValueAsXML(EvalState & state, bool strict,
bool location, XMLWriter & doc, PathSet & context, PathSet & drvsSeen) const bool location, XMLWriter & doc, PathSet & context, PathSet & drvsSeen,
const Pos & pos) const
{ {
doc.writeEmptyElement("unevaluated"); doc.writeEmptyElement("unevaluated");
} }
void printValueAsXML(EvalState & state, bool strict, bool location, void printValueAsXML(EvalState & state, bool strict, bool location,
Value & v, std::ostream & out, PathSet & context) Value & v, std::ostream & out, PathSet & context, const Pos & pos)
{ {
XMLWriter doc(true, out); XMLWriter doc(true, out);
XMLOpenElement root(doc, "expr"); XMLOpenElement root(doc, "expr");
PathSet drvsSeen; PathSet drvsSeen;
printValueAsXML(state, strict, location, v, doc, context, drvsSeen); printValueAsXML(state, strict, location, v, doc, context, drvsSeen, pos);
} }

View file

@ -9,6 +9,6 @@
namespace nix { namespace nix {
void printValueAsXML(EvalState & state, bool strict, bool location, void printValueAsXML(EvalState & state, bool strict, bool location,
Value & v, std::ostream & out, PathSet & context); Value & v, std::ostream & out, PathSet & context, const Pos & pos);
} }

View file

@ -94,7 +94,8 @@ class ExternalValueBase
/* Print the value as XML. Defaults to unevaluated */ /* Print the value as XML. Defaults to unevaluated */
virtual void printValueAsXML(EvalState & state, bool strict, bool location, virtual void printValueAsXML(EvalState & state, bool strict, bool location,
XMLWriter & doc, PathSet & context, PathSet & drvsSeen) const; XMLWriter & doc, PathSet & context, PathSet & drvsSeen,
const Pos & pos) const;
virtual ~ExternalValueBase() virtual ~ExternalValueBase()
{ {

View file

@ -50,7 +50,7 @@ void processExpr(EvalState & state, const Strings & attrPaths,
else else
state.autoCallFunction(autoArgs, v, vRes); state.autoCallFunction(autoArgs, v, vRes);
if (output == okXML) if (output == okXML)
printValueAsXML(state, strict, location, vRes, std::cout, context); printValueAsXML(state, strict, location, vRes, std::cout, context, noPos);
else if (output == okJSON) else if (output == okJSON)
printValueAsJSON(state, strict, vRes, std::cout, context); printValueAsJSON(state, strict, vRes, std::cout, context);
else { else {