about summary refs log tree commit diff
path: root/src/libexpr
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-03-02T20·23+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-03-02T20·23+0000
commite14e2399ed5b1ffc30f08d1f30f19d2ceb24dabb (patch)
treebb3827ac5da24d3fb6e13be2a132a34afd4246e5 /src/libexpr
parent158aa8931776c61e19cec62e7cea7c45961fdcc7 (diff)
* Prevent a potential memory corruption problem if an ATerm garbage
  collection happens during fixAttrs().

Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/parser.y8
1 files changed, 7 insertions, 1 deletions
diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y
index c4afb72eacd5..8706ce025477 100644
--- a/src/libexpr/parser.y
+++ b/src/libexpr/parser.y
@@ -85,6 +85,10 @@ static Expr fixAttrs(bool recursive, ATermList as)
 {
     Tree attrs;
 
+    /* This ATermMap is needed to ensure that the `leaf' fields in the
+       Tree nodes are not garbage collected. */
+    ATermMap gcRoots;
+
     for (ATermIterator i(as); i; ++i) {
         ATermList names, attrPath; Expr src, e; ATerm name, pos;
 
@@ -95,7 +99,9 @@ static Expr fixAttrs(bool recursive, ATermList as)
                     throw ParseError(format("duplicate definition of attribute `%1%' at %2%")
                         % showAttrPath(ATmakeList1(*j)) % showPos(pos));
                 Tree & t(attrs.children[*j]);
-                t.leaf = fromScope ? makeVar(*j) : makeSelect(src, *j);
+                Expr leaf = fromScope ? makeVar(*j) : makeSelect(src, *j);
+                gcRoots.set(leaf, leaf);
+                t.leaf = leaf;
                 t.pos = pos;
                 if (recursive && fromScope) t.recursive = false;
             }