Update of /cvsroot/audacity/audacity-src/src/xml
In directory sc8-pr-cvs11.sourceforge.net:/tmp/cvs-serv12696/src/xml

Modified Files:
      Tag: AUDACITY_1_2
        XMLTagHandler.cpp XMLTagHandler.h 
Log Message:
Backport NGS security fixes for UmixIt to AUDACITY_1_2, 
plus a fix to reduce flickering when importing multiple files.

Index: XMLTagHandler.h
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/xml/XMLTagHandler.h,v
retrieving revision 1.4
retrieving revision 1.4.2.1
diff -u -d -r1.4 -r1.4.2.1
--- XMLTagHandler.h     10 Sep 2003 07:42:35 -0000      1.4
+++ XMLTagHandler.h     12 Jan 2007 00:27:51 -0000      1.4.2.1
@@ -5,11 +5,15 @@
   XMLTagHandler.h
 
   Dominic Mazzoni
+  Vaughan Johnson
 
-  This class is an interface which should be implemented by
+  The XMLTagHandler class is an interface which should be implemented by
   classes which wish to be able to load and save themselves
   using XML files.
 
+  The XMLValueChecker class implements static bool methods for checking 
+  input values from XML files.
+
 **********************************************************************/
 
 #include <wx/string.h>
@@ -18,6 +22,29 @@
 #ifndef __AUDACITY_XML_TAG_HANDLER__
 #define __AUDACITY_XML_TAG_HANDLER__
 
+class XMLValueChecker
+{
+public:
+   // "Good" means well-formed and for the file-related functions, names an 
existing file or folder.
+   // These are used in HandleXMLTag and BuildFomXML methods to check the 
input for 
+   // security vulnerabilites, per the NGS report for UmixIt.
+   static bool IsGoodString(const wxString str);
+
+   static bool IsGoodFileName(const wxString strFileName, const wxString 
strDirName = "");
+   static bool IsGoodSubdirName(const wxString strSubdirName, const wxString 
strDirName = "");
+   static bool IsGoodPathName(const wxString strPathName);
+
+   // Note that because wxString::ToLong does additional testing, IsGoodInt 
doesn't duplicate 
+   // that testing, so use wxString::ToLong after IsGoodInt, not just atoi.
+   static bool IsGoodInt(const wxString strInt);
+
+   static bool IsValidChannel(const int nValue); 
+   static bool IsValidSampleFormat(const int nValue); // true if nValue is one 
sampleFormat enum values
+
+private:
+   static bool IsGoodFileString(wxString str);
+};
+
 class XMLTagHandler {
  public:
 

Index: XMLTagHandler.cpp
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/xml/XMLTagHandler.cpp,v
retrieving revision 1.4
retrieving revision 1.4.2.1
diff -u -d -r1.4 -r1.4.2.1
--- XMLTagHandler.cpp   10 Sep 2003 19:56:31 -0000      1.4
+++ XMLTagHandler.cpp   12 Jan 2007 00:27:50 -0000      1.4.2.1
@@ -2,14 +2,18 @@
 
   Audacity: A Digital Audio Editor
 
-  XMLTagHandler.h
+  XMLTagHandler.cpp
 
   Dominic Mazzoni
+  Vaughan Johnson
 
-  This class is an interface which should be implemented by
+  The XMLTagHandler class is an interface which should be implemented by
   classes which wish to be able to load and save themselves
   using XML files.
 
+  The XMLValueChecker class implements static bool methods for checking 
+  input values from XML files.
+
 **********************************************************************/
 
 #include "XMLTagHandler.h"
@@ -17,7 +21,126 @@
 #include "../Audacity.h"
 #include "../Internat.h"
 
+#ifdef _WIN32
+   #include <windows.h>
+#endif
+
 #include <wx/defs.h>
+#include <wx/filename.h>
+
+#include "../SampleFormat.h"
+#include "../Track.h"
+
+bool XMLValueChecker::IsGoodString(const wxString str)
+{
+   size_t len = str.Length();
+   int nullIndex = str.Find('\0');
+   if ((len < 2048) && // Shouldn't be any reason for longer strings, except 
intentional file corruption.
+         (nullIndex > -1) && // _Should_ always find it, at string terminator.
+         (nullIndex == len)) // No null characters except terminator.
+      return true;
+   else
+      return false; // good place for a breakpoint
+}
+
+// "Good" means the name is well-formed and names an existing file or folder.
+bool XMLValueChecker::IsGoodFileName(const wxString strFileName, const 
wxString strDirName /* = "" */)
+{
+   // Test strFileName.
+   if (!IsGoodFileString(strFileName)) 
+      return false;
+
+   #ifdef _WIN32
+      if (strFileName.Length() + 1 + strDirName.Length() > MAX_PATH)
+         return false;
+   #endif
+
+   // Test the corresponding wxFileName.
+   wxFileName fileName(FILENAME(strDirName), FILENAME(strFileName));
+   return (fileName.IsOk() && fileName.FileExists());
+}
+
+bool XMLValueChecker::IsGoodSubdirName(const wxString strSubdirName, const 
wxString strDirName /* = "" */)
+{
+   // Test strSubdirName. 
+   // Note this prevents path separators, and relative path to parents 
(strDirName), 
+   // so fixes vulnerability #3 in the NGS report for UmixIt, 
+   // where an attacker could craft an AUP file with relative pathnames to get 
to system files, for example.
+   if (!IsGoodFileString(strSubdirName) || (strSubdirName == ".") || 
(strSubdirName == ".."))
+      return false;
+
+   #ifdef _WIN32
+      if (strSubdirName.Length() + 1 + strDirName.Length() > MAX_PATH)
+         return false;
+   #endif
+
+   // Test the corresponding wxFileName.
+   wxFileName fileName(FILENAME(strDirName), FILENAME(strSubdirName));
+   return (fileName.IsOk() && fileName.DirExists());
+}
+
+bool XMLValueChecker::IsGoodPathName(const wxString strPathName)
+{
+   // Test the corresponding wxFileName.
+   wxFileName fileName(FILENAME(strPathName));
+   return XMLValueChecker::IsGoodFileName(fileName.GetFullName(), 
fileName.GetPath(wxPATH_GET_VOLUME));
+}
+
+bool XMLValueChecker::IsGoodFileString(wxString str)
+{
+   return (IsGoodString(str) && 
+            !str.IsEmpty() && 
+            (str.Length() <= 260) && // FILENAME_MAX is 260 in MSVC, but 
inconsistent across platforms, sometimes huge.
+            (str.Find(wxFileName::GetPathSeparator()) == -1)); // No path 
separator characters. //vvv (this won't work on CVS HEAD)
+}
+
+bool XMLValueChecker::IsGoodInt(const wxString strInt)
+{
+   if (!IsGoodString(strInt))
+      return false;
+
+   // Check that the value won't overflow.
+   // Signed long: -2,147,483,648 to +2,147,483,647, i.e., -2^31 to 2^31-1
+   // We're strict about disallowing spaces and commas, and requiring minus 
sign to be first char for negative.
+   const size_t lenMAXABS = strlen("2147483647");
+   const size_t lenStrInt = strInt.Length();
+
+   unsigned long nTest;
+   wxString strTest;
+
+   if (lenStrInt > (lenMAXABS + 1))
+      return false;
+   else if ((lenStrInt == (lenMAXABS + 1)) && (strInt[0] == '-'))
+   {
+      const unsigned long digitsMAXABS[] = {2, 1, 4, 7, 4, 8, 3, 6, 4, 8};
+      for (unsigned int i = 0; i < lenMAXABS; i++) {
+         strTest = strInt[i+1];
+         if (!strTest.ToULong(&nTest) || (nTest > digitsMAXABS[i]))
+            return false;
+      }
+   }
+   else if (lenStrInt == lenMAXABS)
+   {
+      const unsigned long digitsMAXABS[] = {2, 1, 4, 7, 4, 8, 3, 6, 4, 7};
+      for (unsigned int i = 0; i < lenMAXABS; i++) {
+         strTest = strInt[i];
+         if (!strTest.ToULong(&nTest) || (nTest > digitsMAXABS[i]))
+            return false;
+      }
+   }
+   return true;
+}
+
+bool XMLValueChecker::IsValidChannel(const int nValue)
+{
+   return (nValue >= Track::LeftChannel) && (nValue <= Track::MonoChannel);
+}
+
+bool XMLValueChecker::IsValidSampleFormat(const int nValue)
+{
+   return (nValue == int16Sample) || (nValue == int24Sample) || (nValue == 
floatSample);
+}
+
 
 // See http://www.w3.org/TR/REC-xml for reference
 wxString XMLTagHandler::XMLEsc(wxString s)


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Audacity-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/audacity-cvs

Reply via email to