Bug 598289 - Fix bad parsing of CF_HTML values. r=roc
authorBrian R. Bondy <netzen@gmail.com>
Wed, 21 Sep 2011 13:22:53 -0400
changeset 77278 b7486f31f6b1d29d60098ba74bc2ba0c0e2d17c5
parent 77277 16c9cfa0cf8401400e1f9acc9a42964b601c1261
child 77279 9e3562fefd4ca1970d8f7ba430b582e7dc6092bb
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
reviewersroc
bugs598289
milestone9.0a1
Bug 598289 - Fix bad parsing of CF_HTML values. r=roc
widget/src/windows/nsClipboard.cpp
--- a/widget/src/windows/nsClipboard.cpp
+++ b/widget/src/windows/nsClipboard.cpp
@@ -688,33 +688,57 @@ nsresult nsClipboard::GetDataFromDataObj
 //
 // FindPlatformHTML
 //
 // Someone asked for the OS CF_HTML flavor. We give it back to them exactly as-is.
 //
 PRBool
 nsClipboard :: FindPlatformHTML ( IDataObject* inDataObject, UINT inIndex, void** outData, PRUint32* outDataLen )
 {
-  PRBool dataFound = PR_FALSE;
+  // Reference: MSDN doc entitled "HTML Clipboard Format"
+  // http://msdn.microsoft.com/en-us/library/aa767917(VS.85).aspx#unknown_854
+  // CF_HTML is UTF8, not unicode. We also can't rely on it being null-terminated
+  // so we have to check the CF_HTML header for the correct length. 
+  // The length we return is the bytecount from the beginning of the selected data to the end
+  // of the selected data, without the null termination. Because it's UTF8, we're guaranteed 
+  // the header is ASCII.
 
-  if ( outData && *outData ) {
-    // CF_HTML is UTF8, not unicode. We also can't rely on it being null-terminated
-    // so we have to check the CF_HTML header for the correct length. The length we return
-    // is the bytecount from the beginning of the data to the end, without
-    // the null termination. Because it's UTF8, we're guaranteed the header is ascii (yay!).
-    float vers = 0.0;
-    PRUint32 startOfData = 0;
-    sscanf((char*)*outData, "Version:%f\nStartHTML:%u\nEndHTML:%u", &vers, &startOfData, outDataLen);
-    NS_ASSERTION(startOfData && *outDataLen, "Couldn't parse CF_HTML description header");
- 
-    if ( *outDataLen )
-      dataFound = PR_TRUE;
+  if (!outData || !*outData) {
+    return PR_FALSE;
   }
 
-  return dataFound;
+  float vers = 0.0;
+  PRInt32 startOfData = 0;
+  PRInt32 endOfData = 0;
+  int numFound = sscanf((char*)*outData, "Version:%f\nStartHTML:%d\nEndHTML:%d", 
+                        &vers, &startOfData, &endOfData);
+
+  if (numFound != 3 || startOfData < -1 || endOfData < -1) {
+    return PR_FALSE;
+  }
+
+  // Fixup the start and end markers if they have no context (set to -1)
+  if (startOfData == -1) {
+    startOfData = 0;
+  }
+  if (endOfData == -1) {
+    endOfData = *outDataLen;
+  }
+
+  // Make sure we were passed sane values within our buffer size.
+  if (!endOfData || startOfData >= endOfData || 
+      endOfData > *outDataLen) {
+    return PR_FALSE;
+  }
+  
+  // We want to return the buffer not offset by startOfData because it will be 
+  // parsed out later (probably by nsHTMLEditor::ParseCFHTML) when it is still
+  // in CF_HTML format.
+  *outDataLen = endOfData;
+  return PR_TRUE;
 }
 
 
 //
 // FindUnicodeFromPlainText
 //
 // we are looking for text/unicode and we failed to find it on the clipboard first,
 // try again with text/plain. If that is present, convert it to unicode.