зеркало из https://github.com/mozilla/gecko-dev.git
Make CF_HTML a different flavor and return it to editor w/out any
modification. Bulletproof the data we get from the OS by always null terminating it. r=brade/sr=kin bug# 69566.
This commit is contained in:
Родитель
6544c60210
Коммит
3ba174b7c8
|
@ -39,6 +39,7 @@
|
|||
#define kFileMime "application/x-moz-file"
|
||||
#define kURLMime "text/x-moz-url"
|
||||
#define kNativeImageMime "application/x-moz-nativeimage"
|
||||
#define kNativeHTMLMime "application/x-moz-nativehtml"
|
||||
|
||||
%}
|
||||
|
||||
|
|
|
@ -105,8 +105,8 @@ UINT nsClipboard::GetFormat(const char* aMimeStr)
|
|||
format = CF_HDROP;
|
||||
else if (mimeStr.Equals(kURLMime))
|
||||
format = CF_UNICODETEXT;
|
||||
else if (mimeStr.Equals(kHTMLMime))
|
||||
format = nsClipboard::CF_HTML;
|
||||
else if (mimeStr.Equals(kNativeHTMLMime))
|
||||
format = CF_HTML;
|
||||
else
|
||||
format = ::RegisterClipboardFormat(aMimeStr);
|
||||
|
||||
|
@ -249,18 +249,22 @@ NS_IMETHODIMP nsClipboard::SetNativeClipboardData ( PRInt32 aWhichClipboard )
|
|||
nsresult nsClipboard::GetGlobalData(HGLOBAL aHGBL, void ** aData, PRUint32 * aLen)
|
||||
{
|
||||
// Allocate a new memory buffer and copy the data from global memory.
|
||||
// Recall that win98 allocates to nearest DWORD boundary.
|
||||
// Recall that win98 allocates to nearest DWORD boundary. As a safety
|
||||
// precaution, allocate an extra 2 bytes (but don't report them!) and
|
||||
// null them out to ensure that all of our strlen calls will succeed.
|
||||
nsresult result = NS_ERROR_FAILURE;
|
||||
if (aHGBL != NULL) {
|
||||
LPSTR lpStr = (LPSTR)::GlobalLock(aHGBL);
|
||||
DWORD allocSize = ::GlobalSize(aHGBL);
|
||||
char* data = NS_STATIC_CAST(char*, nsMemory::Alloc(allocSize));
|
||||
char* data = NS_STATIC_CAST(char*, nsMemory::Alloc(allocSize + sizeof(PRUnichar)));
|
||||
if ( data ) {
|
||||
memcpy ( data, lpStr, allocSize );
|
||||
|
||||
memcpy ( data, lpStr, allocSize );
|
||||
data[allocSize] = data[allocSize + 1] = '\0'; // null terminate for safety
|
||||
|
||||
::GlobalUnlock(aHGBL);
|
||||
*aData = data;
|
||||
*aLen = allocSize;
|
||||
|
||||
result = NS_OK;
|
||||
}
|
||||
}
|
||||
|
@ -487,11 +491,10 @@ nsresult nsClipboard::GetNativeDataOffClipboard(IDataObject * aDataObject, UINT
|
|||
if ( NS_SUCCEEDED(GetGlobalData(stm.hGlobal, aData, &allocLen)) ) {
|
||||
if ( fe.cfFormat == CF_HTML ) {
|
||||
// CF_HTML is actually UTF8, not unicode, so disregard the assumption
|
||||
// above. We have to keep the null termination because of bugs in
|
||||
// nsDependentCString (141866). The string will be stripped of its null by
|
||||
// conversion to unicode in GetDataFromDataObject(), so it'll all
|
||||
// end up well.
|
||||
*aLen = strlen ( NS_REINTERPRET_CAST(char*, *aData) ) + sizeof(char);
|
||||
// above. We have to check the header for the actual length, and we'll
|
||||
// do that in FindPlatformHTML(). For now, return the allocLen. This
|
||||
// case is mostly to ensure we don't try to call strlen on the buffer.
|
||||
*aLen = allocLen;
|
||||
}
|
||||
else
|
||||
*aLen = nsCRT::strlen(NS_REINTERPRET_CAST(PRUnichar*, *aData)) * sizeof(PRUnichar);
|
||||
|
@ -586,32 +589,16 @@ nsresult nsClipboard::GetDataFromDataObject(IDataObject * aDataObject,
|
|||
if ( NS_SUCCEEDED(NS_NewNativeLocalFile(filepath, PR_FALSE, getter_AddRefs(file))) )
|
||||
genericDataWrapper = do_QueryInterface(file);
|
||||
}
|
||||
else if ( strcmp(flavorStr, kHTMLMime) == 0 ) {
|
||||
// CF_HTML is different from what we want as html. Munge the data appropriately.
|
||||
|
||||
// convert the win32 line endings to DOM line endings. We do this first to
|
||||
// avoid another copy since we can't replace the converter's buffer in situ.
|
||||
// CF_HTML is UTF8, so tell the converter we have text/plain so that it does
|
||||
// single byte conversion.
|
||||
PRInt32 signedLen = NS_STATIC_CAST(PRInt32, dataLen);
|
||||
nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks ( kTextMime, &data, &signedLen );
|
||||
|
||||
// Convert from CF_HTML to gecko's html data flavor. Details of the CF_HTML format
|
||||
// can be found at:
|
||||
// http://msdn.microsoft.com/workshop/networking/clipboard/htmlclipboard.asp
|
||||
//
|
||||
// Essentially, we strip off all the header info and return everything else. I think
|
||||
// it's safe to assume that the fragment will always contain <!DOCTYPE> at the beginning
|
||||
// of the actual data, so look for that.
|
||||
char* headerStart = strchr((char*)data, '<');
|
||||
if ( headerStart ) {
|
||||
// gecko expects HTML in unicode, but CF_HTML is in UTF8. Convert it
|
||||
NS_ConvertUTF8toUCS2 converter ( headerStart );
|
||||
dataLen = converter.Length() * sizeof(PRUnichar);
|
||||
nsPrimitiveHelpers::CreatePrimitiveForData ( flavorStr, (void*)converter.get(), dataLen, getter_AddRefs(genericDataWrapper) );
|
||||
}
|
||||
else if ( strcmp(flavorStr, kNativeHTMLMime) == 0) {
|
||||
// the editor folks want CF_HTML exactly as it's on the clipboard, no conversions,
|
||||
// no fancy stuff. Pull it off the clipboard, stuff it into a wrapper and hand
|
||||
// it back to them.
|
||||
if ( FindPlatformHTML(aDataObject, anIndex, &data, &dataLen) )
|
||||
nsPrimitiveHelpers::CreatePrimitiveForData ( flavorStr, data, dataLen, getter_AddRefs(genericDataWrapper) );
|
||||
else
|
||||
continue; // something wrong with this flavor, keep looking for other data
|
||||
}
|
||||
else {
|
||||
else {
|
||||
// we probably have some form of text. The DOM only wants LF, so convert from Win32 line
|
||||
// endings to DOM line endings.
|
||||
PRInt32 signedLen = NS_STATIC_CAST(PRInt32, dataLen);
|
||||
|
@ -639,6 +626,35 @@ nsresult nsClipboard::GetDataFromDataObject(IDataObject * aDataObject,
|
|||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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;
|
||||
|
||||
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:%d\nEndHTML:%d", &vers, &startOfData, outDataLen);
|
||||
NS_ASSERTION(startOfData && *outDataLen, "Couldn't parse CF_HTML description header");
|
||||
|
||||
if ( *outDataLen )
|
||||
dataFound = PR_TRUE;
|
||||
}
|
||||
|
||||
return dataFound;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// FindURLFromLocalFile
|
||||
//
|
||||
|
|
|
@ -84,6 +84,7 @@ protected:
|
|||
static PRBool IsInternetShortcut ( const char* inFileName ) ;
|
||||
static PRBool FindURLFromLocalFile ( IDataObject* inDataObject, UINT inIndex, void** outData, PRUint32* outDataLen ) ;
|
||||
static PRBool FindUnicodeFromPlainText ( IDataObject* inDataObject, UINT inIndex, void** outData, PRUint32* outDataLen ) ;
|
||||
static PRBool FindPlatformHTML ( IDataObject* inDataObject, UINT inIndex, void** outData, PRUint32* outDataLen );
|
||||
static void ResolveShortcut ( const char* inFileName, char** outURL ) ;
|
||||
|
||||
nsIWidget * mWindow;
|
||||
|
|
|
@ -55,8 +55,8 @@
|
|||
//
|
||||
// Given some data and the flavor it corresponds to, creates the appropriate
|
||||
// nsISupports* wrapper for passing across IDL boundaries. Right now, everything
|
||||
// creates a two-byte |nsISupportsWString|, even "text/plain" since it is decoded
|
||||
// from the native platform charset into unicode.
|
||||
// creates a two-byte |nsISupportsWString|, except for "text/plain" and native
|
||||
// platform HTML (CF_HTML on win32)
|
||||
//
|
||||
void
|
||||
nsPrimitiveHelpers :: CreatePrimitiveForData ( const char* aFlavor, void* aDataBuff,
|
||||
|
@ -65,7 +65,7 @@ nsPrimitiveHelpers :: CreatePrimitiveForData ( const char* aFlavor, void* aDataB
|
|||
if ( !aPrimitive )
|
||||
return;
|
||||
|
||||
if ( strcmp(aFlavor,kTextMime) == 0 ) {
|
||||
if ( strcmp(aFlavor,kTextMime) == 0 || strcmp(aFlavor,kNativeHTMLMime) == 0 ) {
|
||||
nsCOMPtr<nsISupportsString> primitive;
|
||||
nsComponentManager::CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, nsnull,
|
||||
NS_GET_IID(nsISupportsString), getter_AddRefs(primitive));
|
||||
|
|
Загрузка…
Ссылка в новой задаче