瀏覽代碼

loading an empty xml stream, created wrong root node type

Noticed in Dali, when loading a 0 length store file.
The IPTreeMaker used to load, created a standard impl. of a IPropertyTree,
when it should have/needed to ask the maker to create the appropriate type.

The result (in Dali) was that it assumed all nodes were of the correct impl.
(CServerRemoteTree) and crashed accessing it via a cast.

NB: only an issue when loading an empty file/stream

Signed-off-by: Jake Smith <jake.smith@lexisnexis.com>
Jake Smith 13 年之前
父節點
當前提交
1e11a0dc10
共有 4 個文件被更改,包括 24 次插入14 次删除
  1. 18 13
      common/thorhelper/thorxmlread.cpp
  2. 1 1
      system/jlib/jptree.cpp
  3. 1 0
      system/jlib/jptree.hpp
  4. 4 0
      system/jlib/jptree.ipp

+ 18 - 13
common/thorhelper/thorxmlread.cpp

@@ -1619,6 +1619,7 @@ class CXMLParse : public CInterface, implements IXMLParse
         CopyCIArrayOf<CParseStackInfo> stack, freeParseInfo;
         IPTreeMaker *maker;
         Linked<CMarkReadBase> marking;
+        Owned<COffsetNodeCreator> nodeCreator;
         void *utf8Translator;
         unsigned level;
         bool contentRequired;
@@ -1647,25 +1648,13 @@ class CXMLParse : public CInterface, implements IXMLParse
         void init()
         {
             level = 0;
-            Owned<COffsetNodeCreator> nodeCreator = new COffsetNodeCreator();
+            nodeCreator.setown(new COffsetNodeCreator());
             maker = createRootLessPTreeMaker(ipt_none, NULL, nodeCreator);
             bool f;
             utf8Translator = rtlOpenCodepageConverter("utf-8", "latin1", f);
             if (f)
                 throw MakeStringException(0, "Failed to initialize unicode utf-8 translator");
         }
-        void reset()
-        {
-            level = 0;
-            ForEachItemIn(i, stack)
-                delete &stack.item(i);
-            ForEachItemIn(i2, freeParseInfo)
-                delete &freeParseInfo.item(i2);
-            stack.kill();
-            freeParseInfo.kill();
-            if (marking)
-                marking->reset();
-        }
         void setMarkingStream(CMarkReadBase &_marking) { marking.set(&_marking); }
         CXPath &queryXPath() { return xpath; }
 
@@ -1896,6 +1885,22 @@ class CXMLParse : public CInterface, implements IXMLParse
         }
         virtual IPropertyTree *queryRoot() { return maker->queryRoot(); }
         virtual IPropertyTree *queryCurrentNode() { return maker->queryCurrentNode(); }
+        virtual void reset()
+        {
+            level = 0;
+            ForEachItemIn(i, stack)
+                delete &stack.item(i);
+            ForEachItemIn(i2, freeParseInfo)
+                delete &freeParseInfo.item(i2);
+            stack.kill();
+            freeParseInfo.kill();
+            if (marking)
+                marking->reset();
+        }
+        virtual IPropertyTree *create(const char *tag)
+        {
+            return nodeCreator->create(tag);
+        }
     } *iXMLMaker;
 
 public:

+ 1 - 1
system/jlib/jptree.cpp

@@ -5104,7 +5104,7 @@ IPropertyTree *createPTree(ISimpleReadStream &stream, byte flags, XmlReaderOptio
     if (iMaker->queryRoot())
         return LINK(iMaker->queryRoot());
     else
-        return createPTree(flags);
+        return iMaker->create(NULL);
 }
 
 IPropertyTree *createPTree(IFileIO &ifileio, byte flags, XmlReaderOptions readFlags, IPTreeMaker *iMaker)

+ 1 - 0
system/jlib/jptree.hpp

@@ -156,6 +156,7 @@ interface IPTreeMaker : extends IPTreeNotifyEvent
     virtual IPropertyTree *queryRoot() = 0;
     virtual IPropertyTree *queryCurrentNode() = 0;
     virtual void reset() = 0;
+    virtual IPropertyTree *create(const char *tag) = 0;
 };
 
 interface IPTreeNodeCreator : extends IInterface

+ 4 - 0
system/jlib/jptree.ipp

@@ -630,6 +630,10 @@ public:
         }
         currentNode = NULL;
     }
+    virtual IPropertyTree *create(const char *tag)
+    {
+        return nodeCreator->create(tag);
+    }
 };
 
 #ifdef __64BIT__