From d1b17740ed4d9b1e3c3ad5898bb8259969dc77df Mon Sep 17 00:00:00 2001
From: Kamil Rojewski <kamil.rojewski@gmail.com>
Date: Wed, 13 Aug 2014 10:38:38 +0200
Subject: [PATCH] fix for stack overflow
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Recursion in item mapping iterator caused a stack
overflow for large datasets.

Task-number: QTBUG-40153
Change-Id: I693798de0ecfd3a920a3dd270172ce7ec3c13d8d
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@digia.com>
---
 .../iterators/qitemmappingiterator_p.h        | 32 +++++++++++--------
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/src/xmlpatterns/iterators/qitemmappingiterator_p.h b/src/xmlpatterns/iterators/qitemmappingiterator_p.h
index 9dc3b45e..3167bd74 100644
--- a/src/xmlpatterns/iterators/qitemmappingiterator_p.h
+++ b/src/xmlpatterns/iterators/qitemmappingiterator_p.h
@@ -115,24 +115,28 @@ namespace QPatternist
          */
         virtual TResult next()
         {
-            const TSource sourceItem(m_it->next());
-
-            if(qIsForwardIteratorEnd(sourceItem))
-            {
-                m_current = TResult();
-                m_position = -1;
-                return TResult();
-            }
-            else
+            while (true)
             {
-                m_current = m_mapper->mapToItem(sourceItem, m_context);
-                if(qIsForwardIteratorEnd(m_current))
-                    return next(); /* The mapper returned null, so continue with the next in the source. */
-                else
+                const TSource &sourceItem = m_it->next();
+                if (qIsForwardIteratorEnd(sourceItem))
                 {
-                    ++m_position;
+                    m_current = TResult();
+                    m_position = -1;
                     return m_current;
                 }
+                else
+                {
+                    m_current = m_mapper->mapToItem(sourceItem, m_context);
+                    if (qIsForwardIteratorEnd(m_current))
+                    {
+                        continue; /* The mapper returned null, so continue with the next in the source. */
+                    }
+                    else
+                    {
+                        ++m_position;
+                        return m_current;
+                    }
+                }
             }
         }
 
-- 
GitLab