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:
pinkerton%netscape.com 2002-05-07 19:45:58 +00:00
Родитель 6544c60210
Коммит 3ba174b7c8
4 изменённых файлов: 57 добавлений и 39 удалений

Просмотреть файл

@ -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));