소스 검색

2008-04-26 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

	Fixed the bug that causes segmentaion fault when reading XML 
containing
	unescapsed character like '&'.
	Also a modification was made which avoids adding unnecessary
	characters stack and appending unused string.
	* src/ExpatMetalinkProcessor.cc
	* src/FileMetalinkParserState.h
	* src/FilesMetalinkParserState.h
	* src/FinMetalinkParserState.h
	* src/HashMetalinkParserState.h
	* src/InitialMetalinkParserState.h
	* src/LanguageMetalinkParserState.h
	* src/MetalinkMetalinkParserState.h
	* src/MetalinkParserState.h
	* src/MetalinkParserStateMachine.cc
	* src/MetalinkParserStateMachine.h
	* src/OSMetalinkParserState.h
	* src/PieceHashMetalinkParserState.h
	* src/PiecesMetalinkParserState.h
	* src/ResourcesMetalinkParserState.h
	* src/SizeMetalinkParserState.h
	* src/SkipTagMetalinkParserState.h
	* src/URLMetalinkParserState.h
	* src/VerificationMetalinkParserState.h
	* src/VersionMetalinkParserState.h
	* src/XML2SAXMetalinkProcessor.cc
Tatsuhiro Tsujikawa 17 년 전
부모
커밋
8678e1f380

+ 28 - 0
ChangeLog

@@ -1,3 +1,31 @@
+2008-04-26  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
+
+	Fixed the bug that causes segmentaion fault when reading XML containing
+	unescapsed character like '&'.
+	Also a modification was made which avoids adding unnecessary
+	characters stack and appending unused string.
+	* src/ExpatMetalinkProcessor.cc
+	* src/FileMetalinkParserState.h
+	* src/FilesMetalinkParserState.h
+	* src/FinMetalinkParserState.h
+	* src/HashMetalinkParserState.h
+	* src/InitialMetalinkParserState.h
+	* src/LanguageMetalinkParserState.h
+	* src/MetalinkMetalinkParserState.h
+	* src/MetalinkParserState.h
+	* src/MetalinkParserStateMachine.cc
+	* src/MetalinkParserStateMachine.h
+	* src/OSMetalinkParserState.h
+	* src/PieceHashMetalinkParserState.h
+	* src/PiecesMetalinkParserState.h
+	* src/ResourcesMetalinkParserState.h
+	* src/SizeMetalinkParserState.h
+	* src/SkipTagMetalinkParserState.h
+	* src/URLMetalinkParserState.h
+	* src/VerificationMetalinkParserState.h
+	* src/VersionMetalinkParserState.h
+	* src/XML2SAXMetalinkProcessor.cc
+
 2008-04-26  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
 
 	Added StringFormat class, which internally calls vasprintf.

+ 17 - 7
src/ExpatMetalinkProcessor.cc

@@ -54,7 +54,8 @@ public:
 
 static void mlStartElement(void* userData, const char* name, const char** attrs)
 {
-  ((SessionData*)userData)->_charactersStack.push_front(std::string());
+  SessionData* sd = reinterpret_cast<SessionData*>(userData);
+
   std::map<std::string, std::string> attrmap;
   if(attrs) {
     const char** p = attrs;
@@ -67,20 +68,29 @@ static void mlStartElement(void* userData, const char* name, const char** attrs)
       attrmap[name] = value;
     }
   }
-  ((SessionData*)userData)->_stm->beginElement(name, attrmap);
+  sd->_stm->beginElement(name, attrmap);
+  if(sd->_stm->needsCharactersBuffering()) {
+    sd->_charactersStack.push_front(std::string());
+  }
 }
 
 static void mlEndElement(void* userData, const char* name)
 {
-  SessionData* sd = (SessionData*)userData;
-
-  sd->_stm->endElement(name, Util::trim(sd->_charactersStack.front()));
-  sd->_charactersStack.pop_front();
+  SessionData* sd = reinterpret_cast<SessionData*>(userData);
+  std::string characters;
+  if(sd->_stm->needsCharactersBuffering()) {
+    characters = Util::trim(sd->_charactersStack.front());
+    sd->_charactersStack.pop_front();
+  }
+  sd->_stm->endElement(name, characters);
 }
 
 static void mlCharacters(void* userData, const char* ch, int len)
 {
-  ((SessionData*)userData)->_charactersStack.front() += std::string(&ch[0], &ch[len]);
+  SessionData* sd = reinterpret_cast<SessionData*>(userData);
+  if(sd->_stm->needsCharactersBuffering()) {
+    sd->_charactersStack.front() += std::string(&ch[0], &ch[len]);
+  }
 }
 
 ExpatMetalinkProcessor::ExpatMetalinkProcessor() {}

+ 5 - 0
src/FileMetalinkParserState.h

@@ -47,6 +47,11 @@ public:
 
   void endElement(MetalinkParserStateMachine* stm,
 		  const std::string& name, const std::string& characters);
+
+  virtual bool needsCharactersBuffering() const
+  {
+    return true;
+  }
 };
 
 } // namespace aria2

+ 5 - 0
src/FilesMetalinkParserState.h

@@ -47,6 +47,11 @@ public:
 
   void endElement(MetalinkParserStateMachine* stm,
 		  const std::string& name, const std::string& characters);
+
+  virtual bool needsCharactersBuffering() const
+  {
+    return true;
+  }
 };
 
 } // namespace aria2

+ 5 - 0
src/FinMetalinkParserState.h

@@ -47,6 +47,11 @@ public:
 
   void endElement(MetalinkParserStateMachine* stm,
 		  const std::string& name, const std::string& characters);
+
+  virtual bool needsCharactersBuffering() const
+  {
+    return false;
+  }
 };
 
 } // namespace aria2

+ 5 - 0
src/HashMetalinkParserState.h

@@ -47,6 +47,11 @@ public:
 
   void endElement(MetalinkParserStateMachine* stm,
 		  const std::string& name, const std::string& characters);
+
+  virtual bool needsCharactersBuffering() const
+  {
+    return true;
+  }
 };
 
 } // namespace aria2

+ 5 - 0
src/InitialMetalinkParserState.h

@@ -47,6 +47,11 @@ public:
 
   void endElement(MetalinkParserStateMachine* stm,
 		  const std::string& name, const std::string& characters);
+
+  virtual bool needsCharactersBuffering() const
+  {
+    return false;
+  }
 };
 
 } // namespace aria2

+ 5 - 0
src/LanguageMetalinkParserState.h

@@ -47,6 +47,11 @@ public:
 
   void endElement(MetalinkParserStateMachine* stm,
 		  const std::string& name, const std::string& characters);
+
+  virtual bool needsCharactersBuffering() const
+  {
+    return true;
+  }
 };
 
 } // namespace aria2

+ 5 - 0
src/MetalinkMetalinkParserState.h

@@ -47,6 +47,11 @@ public:
 
   void endElement(MetalinkParserStateMachine* stm,
 		  const std::string& name, const std::string& characters);
+
+  virtual bool needsCharactersBuffering() const
+  {
+    return false;
+  }
 };
 
 } // namespace aria2

+ 2 - 0
src/MetalinkParserState.h

@@ -51,6 +51,8 @@ public:
   
   virtual void endElement(MetalinkParserStateMachine* stm,
 			  const std::string& name, const std::string& characters) = 0;
+
+  virtual bool needsCharactersBuffering() const = 0;
 };
 
 } // namespace aria2

+ 5 - 0
src/MetalinkParserStateMachine.cc

@@ -324,6 +324,11 @@ void MetalinkParserStateMachine::endElement(const std::string& name, const std::
   _state->endElement(this, name, characters);
 }
 
+bool MetalinkParserStateMachine::needsCharactersBuffering() const
+{
+  return _state->needsCharactersBuffering();
+}
+
 SharedHandle<Metalinker> MetalinkParserStateMachine::getResult() const
 {
   return _ctrl->getResult();

+ 2 - 0
src/MetalinkParserStateMachine.h

@@ -173,6 +173,8 @@ public:
 
   void cancelChunkChecksumTransaction();
 
+  bool needsCharactersBuffering() const;
+
   SharedHandle<Metalinker> getResult() const;
 };
 

+ 5 - 0
src/OSMetalinkParserState.h

@@ -47,6 +47,11 @@ public:
 
   void endElement(MetalinkParserStateMachine* stm,
 		  const std::string& name, const std::string& characters);
+
+  virtual bool needsCharactersBuffering() const
+  {
+    return true;
+  }
 };
 
 } // namespace aria2

+ 5 - 0
src/PieceHashMetalinkParserState.h

@@ -47,6 +47,11 @@ public:
 
   void endElement(MetalinkParserStateMachine* stm,
 		  const std::string& name, const std::string& characters);
+
+  virtual bool needsCharactersBuffering() const
+  {
+    return true;
+  }
 };
 
 } // namespace aria2

+ 5 - 0
src/PiecesMetalinkParserState.h

@@ -47,6 +47,11 @@ public:
 
   void endElement(MetalinkParserStateMachine* stm,
 		  const std::string& name, const std::string& characters);
+
+  virtual bool needsCharactersBuffering() const
+  {
+    return true;
+  }
 };
 
 } // namespace aria2

+ 5 - 0
src/ResourcesMetalinkParserState.h

@@ -47,6 +47,11 @@ public:
 
   void endElement(MetalinkParserStateMachine* stm,
 		  const std::string& name, const std::string& characters);
+
+  virtual bool needsCharactersBuffering() const
+  {
+    return true;
+  }
 };
 
 } // namespace aria2

+ 5 - 0
src/SizeMetalinkParserState.h

@@ -47,6 +47,11 @@ public:
 
   void endElement(MetalinkParserStateMachine* stm,
 		  const std::string& name, const std::string& characters);
+
+  virtual bool needsCharactersBuffering() const
+  {
+    return true;
+  }
 };
 
 } // namespace aria2

+ 5 - 0
src/SkipTagMetalinkParserState.h

@@ -53,6 +53,11 @@ public:
   void endElement(MetalinkParserStateMachine* stm,
 		  const std::string& name, const std::string& characters);
 
+  virtual bool needsCharactersBuffering() const
+  {
+    return false;
+  }
+
   MetalinkParserState* getPreviousState() const
   {
     return _prevState;

+ 5 - 0
src/URLMetalinkParserState.h

@@ -47,6 +47,11 @@ public:
 
   void endElement(MetalinkParserStateMachine* stm,
 		  const std::string& name, const std::string& characters);
+
+  virtual bool needsCharactersBuffering() const
+  {
+    return true;
+  }
 };
 
 } // namespace aria2

+ 5 - 0
src/VerificationMetalinkParserState.h

@@ -47,6 +47,11 @@ public:
 
   void endElement(MetalinkParserStateMachine* stm,
 		  const std::string& name, const std::string& characters);
+
+  virtual bool needsCharactersBuffering() const
+  {
+    return true;
+  }
 };
 
 } // namespace aria2

+ 5 - 0
src/VersionMetalinkParserState.h

@@ -47,6 +47,11 @@ public:
 
   void endElement(MetalinkParserStateMachine* stm,
 		  const std::string& name, const std::string& characters);
+
+  virtual bool needsCharactersBuffering() const
+  {
+    return true;
+  }
 };
 
 } // namespace aria2

+ 16 - 7
src/XML2SAXMetalinkProcessor.cc

@@ -54,7 +54,7 @@ public:
 
 static void mlStartElement(void* userData, const xmlChar* name, const xmlChar** attrs)
 {
-  ((SessionData*)userData)->_charactersStack.push_front(std::string());
+  SessionData* sd = reinterpret_cast<SessionData*>(userData);
   std::map<std::string, std::string> attrmap;
   if(attrs) {
     const xmlChar** p = attrs;
@@ -67,20 +67,29 @@ static void mlStartElement(void* userData, const xmlChar* name, const xmlChar**
       attrmap[name] = value;
     }
   }
-  ((SessionData*)userData)->_stm->beginElement((const char*)name, attrmap);
+  sd->_stm->beginElement((const char*)name, attrmap);
+  if(sd->_stm->needsCharactersBuffering()) {
+    sd->_charactersStack.push_front(std::string());
+  }
 }
 
 static void mlEndElement(void* userData, const xmlChar* name)
 {
-  SessionData* sd = (SessionData*)userData;
-
-  sd->_stm->endElement((const char*)name, Util::trim(sd->_charactersStack.front()));
-  sd->_charactersStack.pop_front();
+  SessionData* sd = reinterpret_cast<SessionData*>(userData);
+  std::string characters;
+  if(sd->_stm->needsCharactersBuffering()) {
+    characters = Util::trim(sd->_charactersStack.front());
+    sd->_charactersStack.pop_front();
+  }
+  sd->_stm->endElement((const char*)name, characters);
 }
 
 static void mlCharacters(void* userData, const xmlChar* ch, int len)
 {
-  ((SessionData*)userData)->_charactersStack.front() += std::string(&ch[0], &ch[len]);
+  SessionData* sd = reinterpret_cast<SessionData*>(userData);
+  if(sd->_stm->needsCharactersBuffering()) {
+    sd->_charactersStack.front() += std::string(&ch[0], &ch[len]);
+  }
 }
 
 static xmlSAXHandler mySAXHandler =