@@ -1480,96 +1480,104 @@ HRESULT nsDataObj::GetPreferredDropEffect(FORMATETC& aFE, STGMEDIUM& aSTG) {
1480
1480
// -----------------------------------------------------
1481
1481
HRESULT nsDataObj::GetText (const nsACString& aDataFlavor, FORMATETC& aFE,
1482
1482
STGMEDIUM& aSTG) {
1483
- void * data = nullptr ;
1483
+ // assignDataToStg
1484
+ //
1485
+ // Helper function to fill the STG with a block of data.
1486
+ auto const assignDataToStg = [&aSTG](void * data, size_t extent) -> HRESULT {
1487
+ aSTG.tymed = TYMED_HGLOBAL;
1488
+ aSTG.pUnkForRelease = nullptr ;
1489
+
1490
+ ScopedOLEMemory<char []> hGlobalMemory (extent);
1491
+ if (hGlobalMemory) {
1492
+ auto dest = hGlobalMemory.lock ();
1493
+ memcpy (dest.get (), data, extent);
1494
+ }
1495
+
1496
+ aSTG.hGlobal = hGlobalMemory.forget ();
1497
+
1498
+ return S_OK;
1499
+ };
1484
1500
1485
1501
const nsPromiseFlatCString& flavorStr = PromiseFlatCString (aDataFlavor);
1486
1502
1487
- // NOTE: CreateDataFromPrimitive creates new memory, that needs to be deleted
1488
1503
nsCOMPtr<nsISupports> genericDataWrapper;
1489
1504
nsresult rv = mTransferable ->GetTransferData (
1490
1505
flavorStr.get (), getter_AddRefs (genericDataWrapper));
1491
1506
if (NS_FAILED(rv) || !genericDataWrapper) {
1492
1507
return E_FAIL;
1493
1508
}
1494
1509
1495
- uint32_t len;
1496
- nsPrimitiveHelpers::CreateDataFromPrimitive (
1497
- nsDependentCString (flavorStr.get ()), genericDataWrapper, &data, &len);
1510
+ // data is a possibly-wide NUL-terminated string. len is its strlen() -- not
1511
+ // its allocation length!
1512
+ auto const [data, len] = [&]() {
1513
+ void * data = nullptr ;
1514
+ uint32_t len;
1515
+ nsPrimitiveHelpers::CreateDataFromPrimitive (
1516
+ nsDependentCString (flavorStr.get ()), genericDataWrapper, &data, &len);
1517
+ return std::tuple{data, size_t (len)};
1518
+ }();
1498
1519
if (!data) return E_FAIL;
1499
1520
1500
- HGLOBAL hGlobalMemory = nullptr ;
1501
-
1502
- aSTG.tymed = TYMED_HGLOBAL;
1503
- aSTG.pUnkForRelease = nullptr ;
1521
+ // CreateDataFromPrimitive allocates memory; free it on exit.
1522
+ auto const _release_data =
1523
+ mozilla::MakeScopeExit ([data = data]() { ::free (data); });
1504
1524
1505
- // We play games under the hood and advertise flavors that we know we
1506
- // can support, only they require a bit of conversion or munging of the data.
1507
- // Do that here.
1525
+ // We play games under the hood and advertise flavors that we know we can
1526
+ // support, only they require a bit of conversion or munging of the data. Do
1527
+ // that here.
1508
1528
//
1509
1529
// The transferable gives us data that is null-terminated, but this isn't
1510
- // reflected in the |len| parameter. Windoze apps expect this null to be there
1530
+ // reflected in the |len| parameter. Windows apps expect this null to be there
1511
1531
// so bump our data buffer by the appropriate size to account for the null
1512
1532
// (one char for CF_TEXT, one char16_t for CF_UNICODETEXT).
1513
- DWORD allocLen = (DWORD)len;
1533
+
1514
1534
if (aFE.cfFormat == CF_TEXT) {
1515
1535
// Someone is asking for text/plain; convert the unicode (assuming it's
1516
1536
// present) to text with the correct platform encoding.
1517
1537
size_t bufferSize = sizeof (char ) * (len + 2 );
1518
1538
char * plainTextData = static_cast <char *>(moz_xmalloc (bufferSize));
1539
+ auto const _release =
1540
+ mozilla::MakeScopeExit ([plainTextData]() { ::free (plainTextData); });
1541
+
1519
1542
char16_t * castedUnicode = reinterpret_cast <char16_t *>(data);
1520
1543
int32_t plainTextLen =
1521
1544
WideCharToMultiByte (CP_ACP, 0 , (LPCWSTR)castedUnicode, len / 2 + 1 ,
1522
1545
plainTextData, bufferSize, NULL , NULL );
1523
- // replace the unicode data with our plaintext data. Recall that
1524
- // |plainTextLen| doesn't include the null in the length.
1525
- free (data);
1546
+
1526
1547
if (plainTextLen) {
1527
- data = plainTextData;
1528
- allocLen = plainTextLen;
1529
- } else {
1530
- free (plainTextData);
1531
- NS_WARNING (" Oh no, couldn't convert unicode to plain text" );
1532
- return S_OK;
1548
+ return assignDataToStg (plainTextData, plainTextLen);
1533
1549
}
1534
- } else if (aFE.cfFormat == nsClipboard::GetHtmlClipboardFormat ()) {
1550
+
1551
+ NS_WARNING (" Oh no, couldn't convert unicode to plain text" );
1552
+ return S_OK;
1553
+ }
1554
+
1555
+ if (aFE.cfFormat == nsClipboard::GetHtmlClipboardFormat ()) {
1535
1556
// Someone is asking for win32's HTML flavor. Convert our html fragment
1536
1557
// from unicode to UTF-8 then put it into a format specified by msft.
1537
1558
NS_ConvertUTF16toUTF8 converter (reinterpret_cast <char16_t *>(data));
1538
1559
char * utf8HTML = nullptr ;
1539
1560
nsresult rv =
1540
1561
BuildPlatformHTML (converter.get (), &utf8HTML); // null terminates
1562
+ auto const _release =
1563
+ mozilla::MakeScopeExit ([utf8HTML]() { ::free (utf8HTML); });
1541
1564
1542
- free (data);
1543
1565
if (NS_SUCCEEDED(rv) && utf8HTML) {
1544
- // replace the unicode data with our HTML data. Don't forget the null.
1545
- data = utf8HTML;
1546
- allocLen = strlen (utf8HTML) + sizeof (char );
1547
- } else {
1548
- NS_WARNING (" Oh no, couldn't convert to HTML" );
1549
- return S_OK;
1566
+ // return our HTML data. Don't forget the null.
1567
+ return assignDataToStg (utf8HTML, strlen (utf8HTML) + sizeof (char ));
1550
1568
}
1551
- } else if (aFE.cfFormat != nsClipboard::GetCustomClipboardFormat ()) {
1552
- // we assume that any data that isn't caught above is unicode. This may
1553
- // be an erroneous assumption, but is true so far.
1554
- allocLen += sizeof (char16_t );
1555
- }
1556
1569
1557
- hGlobalMemory = (HGLOBAL)GlobalAlloc (GMEM_MOVEABLE, allocLen);
1558
-
1559
- // Copy text to Global Memory Area
1560
- if (hGlobalMemory) {
1561
- char * dest = reinterpret_cast <char *>(GlobalLock (hGlobalMemory));
1562
- char * source = reinterpret_cast <char *>(data);
1563
- memcpy (dest, source, allocLen); // copies the null as well
1564
- GlobalUnlock (hGlobalMemory);
1570
+ NS_WARNING (" Oh no, couldn't convert to HTML" );
1571
+ return S_OK;
1565
1572
}
1566
- aSTG.hGlobal = hGlobalMemory;
1567
1573
1568
- // Now, delete the memory that was created by CreateDataFromPrimitive (or our
1569
- // text/plain data)
1570
- free (data);
1574
+ // We assume that any data-format that isn't caught above can be satisfied by
1575
+ // Unicode text. (This may be an erroneous assumption, but seems to have been
1576
+ // true so far.)
1577
+ bool const excludeNull =
1578
+ aFE.cfFormat == nsClipboard::GetCustomClipboardFormat ();
1571
1579
1572
- return S_OK ;
1580
+ return assignDataToStg (data, len + (excludeNull ? 0 : sizeof ( char16_t ))) ;
1573
1581
}
1574
1582
1575
1583
// -----------------------------------------------------
0 commit comments