Fix access to uninitialized values in QtXmlPatterns
authorSami Rosendahl <ext-sami.1.rosendahl@nokia.com>
Tue, 24 Jan 2012 08:43:25 +0000 (10:43 +0200)
committerQt by Nokia <qt-info@nokia.com>
Wed, 1 Feb 2012 12:42:28 +0000 (13:42 +0100)
Fixes valgrind warning like below when executing tst_QXmlQuery::copyConstructor()
  Conditional jump or move depends on uninitialised value(s)
    at: QPatternist::NodeIndexStorage::operator!=(QPatternist::NodeIndexStorage const&) const (qabstractxmlnodemodel.cpp:1220)
    by: QXmlItem::operator=(QXmlItem const&) (qabstractxmlnodemodel.cpp:1228)

Reason for the warning is that QPatternist::NodeIndexStorage::operator!=
accesses all fields of NodeIndexStorage, which are all not intialized in
every execution path of QXmlItem::QXmlItem(const QVariant &) and class
QPatternist::Item constructors.

Fixed by adding NodeIndexStorage::reset() function that resets all fields
and put a call to that function where NodeIndexStorage objects were
previously incompletely initialized. Note that unfortunately class
NodeIndexStorage cannot have a default constructor, because it is used as
a union field.

Change-Id: I758df57551ec49ce8c8b357794177b4e6c454d2f
Sanity-Review: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Dmitry Trofimov
Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
src/xmlpatterns/api/qabstractxmlnodemodel.cpp
src/xmlpatterns/api/qabstractxmlnodemodel.h
src/xmlpatterns/data/qitem_p.h

index 27240f9..6c299dd 100644 (file)
@@ -1138,9 +1138,7 @@ bool QAbstractXmlNodeModel::isDeepEqual(const QXmlNodeModelIndex &n1,
  */
 QXmlItem::QXmlItem()
 {
-    m_node.model = 0;
-    m_node.data = 0;
-    m_node.additionalData = 0;
+    m_node.reset();
 }
 
 bool QXmlItem::internalIsAtomicValue() const
@@ -1164,12 +1162,10 @@ QXmlItem::QXmlItem(const QXmlItem &other) : m_node(other.m_node)
  */
 QXmlItem::QXmlItem(const QVariant &atomicValue)
 {
+    m_node.reset();
     if(atomicValue.isNull())
     {
         /* Then we behave just like the default constructor. */
-        m_node.model = 0;
-        m_node.data = 0;
-        m_node.additionalData = 0;
         return;
     }
 
@@ -1185,13 +1181,6 @@ QXmlItem::QXmlItem(const QVariant &atomicValue)
         m_node.model = reinterpret_cast<const QAbstractXmlNodeModel *>(~0);
         m_atomicValue = temp.asAtomicValue();
     }
-    else
-    {
-        m_atomicValue = 0;
-        m_node.model = 0;
-    }
-
-    m_node.additionalData = 0;
 }
 
 /*!
index abd9443..dcfb388 100644 (file)
@@ -104,6 +104,13 @@ namespace QPatternist
 
         /* Implementation is in qabstractxmlnodemodel.cpp. */
         inline bool operator!=(const NodeIndexStorage &other) const;
+
+        void reset()
+        {
+            data = 0;
+            additionalData = 0;
+            model = 0;
+        }
     };
 }
 
@@ -216,9 +223,7 @@ public:
 
     inline void reset()
     {
-        m_storage.data = 0;
-        m_storage.additionalData = 0;
-        m_storage.model = 0;
+        m_storage.reset();
     }
 
 private:
index 09cca91..020998c 100644 (file)
@@ -207,14 +207,7 @@ namespace QPatternist
          */
         inline Item()
         {
-            /* Note that this function should be equal to reset(). */
-
-            /* This is the area which atomicValue uses. Becauase we want as()
-             * to return null on null-constructed objects, we initialize it. */
-            node.data = 0;
-
-            /* This signals that we're not an atomic value. */
-            node.model = 0;
+            reset();
         }
 
         inline Item(const QXmlNodeModelIndex &n) : node(n.m_storage)
@@ -231,6 +224,7 @@ namespace QPatternist
 
         inline Item(const AtomicValue::Ptr &a)
         {
+            reset();
             if(a)
             {
                 atomicValue = a.data();
@@ -239,14 +233,12 @@ namespace QPatternist
                 /* Signal that we're housing an atomic value. */
                 node.model = reinterpret_cast<const QAbstractXmlNodeModel *>(~0);
             }
-            else
-                node.model = 0; /* Like the default constructor. */
         }
 
         inline Item(const AtomicValue *const a)
         {
             /* Note, the implementation is a copy of the constructor above. */
-
+            reset();
             if(a)
             {
                 atomicValue = a;
@@ -255,8 +247,6 @@ namespace QPatternist
                 /* Signal that we're housing an atomic value. */
                 node.model = reinterpret_cast<const QAbstractXmlNodeModel *>(~0);
             }
-            else
-                node.model = 0; /* Like the default constructor. */
         }
 
         inline ~Item()
@@ -408,10 +398,7 @@ namespace QPatternist
 
         inline void reset()
         {
-            /* Note that this function should be equal to the default
-             * constructor. */
-            node.model = 0;
-            node.data = 0;
+            node.reset();
         }
 
         static inline Item fromPublic(const QXmlItem &i)