- Timestamp:
- Jan 21, 2022 11:41:27 PM (3 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 4 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp
r93399 r93401 513 513 if ( offStart > 0 514 514 && offEnd > 0 515 && offEnd > offStart515 && offEnd >= offStart 516 516 && offEnd <= cch) 517 517 { … … 594 594 Assert(cb); 595 595 596 /* construct CF_HTML formatted string */ 597 598 /* Check that input is zero terminated. */ 599 /** @todo r=bird: Check that it's valid UTF-8 encoded too. */ 600 size_t cchFragment; 601 int rc = RTStrNLenEx(pszSource, cb, &cchFragment); 602 if (!RT_SUCCESS(rc)) 596 /* 597 * Check that input UTF-8 and properly zero terminated. 598 * Note! The zero termination may come earlier than 'cb' - 1, that's fine. 599 */ 600 int rc = RTStrValidateEncodingEx(pszSource, cb, RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED); 601 if (RT_SUCCESS(rc)) 602 { /* likely */ } 603 else 603 604 { 604 605 LogRelFlowFunc(("Error: invalid source fragment. rc = %Rrc\n", rc)); 605 return VERR_INVALID_PARAMETER; 606 } 606 return rc; 607 } 608 size_t const cchFragment = strlen(pszSource); /* Unfortunately the validator doesn't return the length. */ 607 609 608 610 /* 609 @StartHtml - pos before <html> 610 @EndHtml - whole size of text excluding ending zero char 611 @StartFragment - pos after <!--StartFragment--> 612 @EndFragment - pos before <!--EndFragment--> 613 @note: all values includes CR\LF inserted into text 614 Calculations: 615 Header length = format Length + (3*6('digits')) - 2('%s') = format length + 16 (control value - 183) 616 EndHtml = Header length + fragment length 617 StartHtml = 105(constant) 618 StartFragment = 143(constant) 619 EndFragment = Header length + fragment length - 40(ending length) 620 */ 611 * @StartHtml - Absolute offset of <html> 612 * @EndHtml - Size of the whole resulting text (excluding ending zero char) 613 * @StartFragment - Absolute position after <!--StartFragment--> 614 * @EndFragment - Absolute position of <!--EndFragment--> 615 * 616 * Note! The offset are zero padded to max width so we don't have any variations due to those. 617 * Note! All values includes CRLFs inserted into text. 618 * 619 * Calculations: 620 * Header length = Format sample length - 2 ('%s') 621 * EndHtml = Header length + fragment length 622 * StartHtml = 101(constant) 623 * StartFragment = 137(constant) 624 * EndFragment = Header length + fragment length - 38 (ending length) 625 */ 621 626 static const char s_szFormatSample[] = 622 627 /* 0: */ "Version:1.0\r\n" … … 631 636 /* 137+2: */ "<!--EndFragment-->\r\n" 632 637 /* 157+2: */ "</body>\r\n" 633 /* 166+2: */ "</html>\r\n" ;634 /* 175+2: */ 638 /* 166+2: */ "</html>\r\n" 639 /* 175+2: */ ; 635 640 AssertCompile(sizeof(s_szFormatSample) == 175 + 2 + 1); 636 641 637 /* calculate parameters ofCF_HTML header */638 size_t c chHeader = sizeof(s_szFormatSample) - 1;639 size_t offEndHtml = cchHeader + cchFragment;640 size_t offEndFragment = cchHeader + cchFragment - 38; /* 175-137 = 38 */642 /* Calculate parameters of the CF_HTML header */ 643 size_t const cchHeader = sizeof(s_szFormatSample) - 2 /*%s*/ - 1 /*'\0'*/; 644 size_t const offEndHtml = cchHeader + cchFragment; 645 size_t const offEndFragment = cchHeader + cchFragment - 38; /* 175-137 = 38 */ 641 646 char *pszResult = (char *)RTMemAlloc(offEndHtml + 1); 642 if (pszResult == NULL) 643 { 644 LogRelFlowFunc(("Error: Cannot allocate memory for result buffer. rc = %Rrc\n")); 645 return VERR_NO_MEMORY; 646 } 647 648 /* format result CF_HTML string */ 649 size_t cchFormatted = RTStrPrintf(pszResult, offEndHtml + 1, 650 s_szFormatSample, offEndHtml, offEndFragment, pszSource); 647 AssertLogRelReturn(pszResult, VERR_NO_MEMORY); 648 649 /* Format resulting CF_HTML string: */ 650 size_t cchFormatted = RTStrPrintf(pszResult, offEndHtml + 1, s_szFormatSample, offEndHtml, offEndFragment, pszSource); 651 651 Assert(offEndHtml == cchFormatted); 652 652 653 653 #ifdef VBOX_STRICT 654 /* Control calculations. check consistency.*/ 654 /* 655 * Check the calculations. 656 */ 657 658 /* check 'StartFragment:' value */ 655 659 static const char s_szStartFragment[] = "<!--StartFragment-->"; 656 static const char s_szEndFragment[] = "<!--EndFragment-->";657 658 /* check 'StartFragment:' value */659 660 const char *pszRealStartFragment = RTStrStr(pszResult, s_szStartFragment); 660 661 Assert(&pszRealStartFragment[sizeof(s_szStartFragment) - 1] - pszResult == 137); 661 662 662 663 /* check 'EndFragment:' value */ 664 static const char s_szEndFragment[] = "<!--EndFragment-->"; 663 665 const char *pszRealEndFragment = RTStrStr(pszResult, s_szEndFragment); 664 666 Assert((size_t)(pszRealEndFragment - pszResult) == offEndFragment); -
trunk/src/VBox/HostServices/SharedClipboard/testcase/Makefile.kmk
r93115 r93401 53 53 $(PATH_ROOT)/src/VBox/HostServices/common/message.cpp \ 54 54 tstClipboardServiceImpl.cpp 55 tstClipboardServiceImpl_SOURCES.win = \ 56 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp 55 57 tstClipboardServiceImpl_LIBS = $(LIB_RUNTIME) 56 58 tstClipboardServiceImpl_CLEAN = $(tstClipboardServiceImpl_0_OUTDIR)/tstClipboardServiceImpl.run -
trunk/src/VBox/HostServices/SharedClipboard/testcase/tstClipboardServiceImpl.cpp
r93115 r93401 19 19 20 20 #include <VBox/HostServices/VBoxClipboardSvc.h> 21 #ifdef RT_OS_WINDOWS 22 # include <VBox/GuestHost/SharedClipboard-win.h> 23 #endif 21 24 22 25 #include <iprt/assert.h> … … 68 71 69 72 RTTestISub("Setting up client ..."); 73 RTTestIDisableAssertions(); 74 70 75 rc = setupTable(&table); 71 76 RTTESTI_CHECK_MSG_RETV(RT_SUCCESS(rc), ("rc=%Rrc\n", rc)); … … 76 81 rc = shClSvcClientInit(&g_Client, 1 /* clientId */); 77 82 RTTESTI_CHECK_RC_OK(rc); 83 84 RTTestIRestoreAssertions(); 78 85 } 86 87 #ifdef RT_OS_WINDOWS 88 # include "VBoxOrgCfHtml1.h" /* From chrome 97.0.4692.71 */ 89 # include "VBoxOrgMimeHtml1.h" 90 91 static void testHtmlCf(void) 92 { 93 RTTestISub("CF_HTML"); 94 95 char *pszOutput = NULL; 96 uint32_t cbOutput = UINT32_MAX/2; 97 RTTestIDisableAssertions(); 98 RTTESTI_CHECK_RC(SharedClipboardWinConvertCFHTMLToMIME("", 0, &pszOutput, &cbOutput), VERR_INVALID_PARAMETER); 99 RTTestIRestoreAssertions(); 100 101 pszOutput = NULL; 102 cbOutput = UINT32_MAX/2; 103 RTTESTI_CHECK_RC(SharedClipboardWinConvertCFHTMLToMIME((char *)&g_abVBoxOrgCfHtml1[0], g_cbVBoxOrgCfHtml1, 104 &pszOutput, &cbOutput), VINF_SUCCESS); 105 RTTESTI_CHECK(cbOutput == g_cbVBoxOrgMimeHtml1); 106 RTTESTI_CHECK(memcmp(pszOutput, g_abVBoxOrgMimeHtml1, cbOutput) == 0); 107 RTMemFree(pszOutput); 108 109 110 static RTSTRTUPLE const s_aRoundTrips[] = 111 { 112 { RT_STR_TUPLE("") }, 113 { RT_STR_TUPLE("1") }, 114 { RT_STR_TUPLE("12") }, 115 { RT_STR_TUPLE("123") }, 116 { RT_STR_TUPLE("1234") }, 117 { RT_STR_TUPLE("12345") }, 118 { RT_STR_TUPLE("123456") }, 119 { RT_STR_TUPLE("1234567") }, 120 { RT_STR_TUPLE("12345678") }, 121 { RT_STR_TUPLE("123456789") }, 122 { RT_STR_TUPLE("1234567890") }, 123 { RT_STR_TUPLE("<h2>asdfkjhasdflhj</h2>") }, 124 { RT_STR_TUPLE("<h2>asdfkjhasdflhj</h2>\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0") }, 125 { (const char *)g_abVBoxOrgMimeHtml1, sizeof(g_abVBoxOrgMimeHtml1) }, 126 }; 127 128 for (size_t i = 0; i < RT_ELEMENTS(s_aRoundTrips); i++) 129 { 130 int rc; 131 char *pszCfHtml = NULL; 132 uint32_t cbCfHtml = UINT32_MAX/2; 133 rc = SharedClipboardWinConvertMIMEToCFHTML(s_aRoundTrips[i].psz, s_aRoundTrips[i].cch + 1, &pszCfHtml, &cbCfHtml); 134 if (rc == VINF_SUCCESS) 135 { 136 if (strlen(pszCfHtml) + 1 != cbCfHtml) 137 RTTestIFailed("#%u: SharedClipboardWinConvertMIMEToCFHTML(%s, %#zx,,) returned incorrect length: %#x, actual %#zx", 138 i, s_aRoundTrips[i].psz, s_aRoundTrips[i].cch, cbCfHtml, strlen(pszCfHtml) + 1); 139 140 char *pszHtml = NULL; 141 uint32_t cbHtml = UINT32_MAX/4; 142 rc = SharedClipboardWinConvertCFHTMLToMIME(pszCfHtml, (uint32_t)strlen(pszCfHtml), &pszHtml, &cbHtml); 143 if (rc == VINF_SUCCESS) 144 { 145 if (strlen(pszHtml) + 1 != cbHtml) 146 RTTestIFailed("#%u: SharedClipboardWinConvertCFHTMLToMIME(%s, %#zx,,) returned incorrect length: %#x, actual %#zx", 147 i, pszHtml, strlen(pszHtml), cbHtml, strlen(pszHtml) + 1); 148 if (strcmp(pszHtml, s_aRoundTrips[i].psz) != 0) 149 RTTestIFailed("#%u: roundtrip for '%s' LB %#zx failed, ended up with '%s'", 150 i, s_aRoundTrips[i].psz, s_aRoundTrips[i].cch, pszHtml); 151 RTMemFree(pszHtml); 152 } 153 else 154 RTTestIFailed("#%u: SharedClipboardWinConvertCFHTMLToMIME(%s, %#zx,,) returned %Rrc, expected VINF_SUCCESS", 155 i, pszCfHtml, strlen(pszCfHtml), rc); 156 RTMemFree(pszCfHtml); 157 } 158 else 159 RTTestIFailed("#%u: SharedClipboardWinConvertMIMEToCFHTML(%s, %#zx,,) returned %Rrc, expected VINF_SUCCESS", 160 i, s_aRoundTrips[i].psz, s_aRoundTrips[i].cch, rc); 161 } 162 } 163 164 #endif /* RT_OS_WINDOWS */ 165 79 166 80 167 int main(int argc, char *argv[]) … … 93 180 RTTestBanner(hTest); 94 181 95 /* Don't let assertions in the host service panic (core dump) the test cases. */96 RTAssertSetMayPanic(false);97 98 182 /* 99 183 * Run the tests. 100 184 */ 101 185 testAnnounceAndReadData(); 186 #ifdef RT_OS_WINDOWS 187 testHtmlCf(); 188 #endif 102 189 103 190 /*
Note:
See TracChangeset
for help on using the changeset viewer.