Changeset 85828 in vbox for trunk/src/VBox/GuestHost/SharedClipboard
- Timestamp:
- Aug 19, 2020 9:12:33 AM (4 years ago)
- Location:
- trunk/src/VBox/GuestHost/SharedClipboard
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp
r83621 r85828 25 25 #include <iprt/path.h> 26 26 #include <iprt/rand.h> 27 #include <iprt/utf16.h> 27 28 28 29 #include <iprt/errcore.h> … … 457 458 } 458 459 459 /** @todo Delinuxify the code (*Lin* -> *Host*); use AssertLogRel*. */ 460 461 int ShClUtf16GetWinSize(PCRTUTF16 pcwszSrc, size_t cwSrc, size_t *pcwDest) 462 { 463 size_t cwDest, i; 464 465 LogFlowFunc(("pcwszSrc=%.*ls, cwSrc=%u\n", cwSrc, pcwszSrc, cwSrc)); 466 AssertLogRelMsgReturn(pcwszSrc != NULL, ("vboxClipboardUtf16GetWinSize: received a null Utf16 string, returning VERR_INVALID_PARAMETER\n"), VERR_INVALID_PARAMETER); 467 if (cwSrc == 0) 468 { 469 *pcwDest = 0; 470 LogFlowFunc(("empty source string, returning\n")); 460 int ShClUtf16LenUtf8(PCRTUTF16 pcwszSrc, size_t cwcSrc, size_t *pchLen) 461 { 462 AssertPtrReturn(pcwszSrc, VERR_INVALID_POINTER); 463 AssertPtrReturn(pchLen, VERR_INVALID_POINTER); 464 465 size_t chLen = 0; 466 int rc = RTUtf16CalcUtf8LenEx(pcwszSrc, cwcSrc, &chLen); 467 if (RT_SUCCESS(rc)) 468 *pchLen = chLen + 1; /* Include terminator. */ 469 return rc; 470 } 471 472 int ShClConvUtf16CRLFToUtf8LF(PRTUTF16 pwszSrc, size_t cwcSrc, 473 char *pszBuf, size_t cbBuf, size_t *pcbLen) 474 { 475 AssertPtrReturn(pwszSrc, VERR_INVALID_POINTER); 476 AssertReturn (cwcSrc, VERR_INVALID_PARAMETER); 477 AssertPtrReturn(pszBuf, VERR_INVALID_POINTER); 478 AssertPtrReturn(pcbLen, VERR_INVALID_POINTER); 479 480 int rc; 481 482 PRTUTF16 pwszTmp = NULL; 483 size_t cchTmp = 0; 484 485 size_t cbLen = 0; 486 487 /* How long will the converted text be? */ 488 rc = ShClUtf16CRLFLenUtf8(pwszSrc, cwcSrc, &cchTmp); 489 if (RT_SUCCESS(rc)) 490 { 491 if (cchTmp) 492 { 493 pwszTmp = (PRTUTF16)RTMemAlloc(cchTmp * sizeof(RTUTF16)); 494 if (pwszTmp) 495 { 496 rc = ShClConvUtf16CRLFToLF(pwszSrc, cwcSrc, pwszTmp, cchTmp); 497 if (RT_SUCCESS(rc)) 498 rc = RTUtf16ToUtf8Ex(pwszTmp + 1, cchTmp - 1, &pszBuf, cbBuf, &cbLen); 499 500 RTMemFree(reinterpret_cast<void *>(pwszTmp)); 501 } 502 else 503 rc = VERR_NO_MEMORY; 504 } 505 else 506 rc = VERR_NO_DATA; 507 } 508 509 if (RT_SUCCESS(rc)) 510 { 511 *pcbLen = cbLen + 1 /* Include terminator */; 512 } 513 514 LogFlowFuncLeaveRC(rc); 515 return rc; 516 } 517 518 int ShClConvUtf16LFToCRLFA(RTUTF16 *pwcSrc, size_t cwcSrc, 519 PRTUTF16 *ppwszDst, size_t *pcwDst) 520 { 521 AssertPtrReturn(pwcSrc, VERR_INVALID_POINTER); 522 AssertReturn(cwcSrc, VERR_INVALID_PARAMETER); 523 AssertPtrReturn(ppwszDst, VERR_INVALID_POINTER); 524 AssertPtrReturn(pcwDst, VERR_INVALID_POINTER); 525 526 PRTUTF16 pwszDst = NULL; 527 size_t cchDst; 528 529 int rc = ShClUtf16LFLenUtf8(pwcSrc, cwcSrc, &cchDst); 530 if (RT_SUCCESS(rc)) 531 { 532 Assert(cchDst); 533 pwszDst = (PRTUTF16)RTMemAlloc(cchDst * sizeof(RTUTF16)); 534 if (pwszDst) 535 { 536 rc = ShClConvUtf16LFToCRLF(pwcSrc, cwcSrc, pwszDst, cchDst); 537 } 538 else 539 rc = VERR_NO_MEMORY; 540 } 541 542 if (RT_SUCCESS(rc)) 543 { 544 *ppwszDst = pwszDst; 545 *pcwDst = cchDst; 546 } 547 else 548 RTMemFree(pwszDst); 549 550 LogFlowFuncLeaveRC(rc); 551 return rc; 552 } 553 554 int ShClConvUtf8LFToUtf16CRLF(const char *pcSrc, unsigned cbSrc, 555 PRTUTF16 *ppwszDst, size_t *pcwDst) 556 { 557 AssertPtrReturn(pcSrc, VERR_INVALID_POINTER); 558 AssertReturn(cbSrc, VERR_INVALID_PARAMETER); 559 AssertPtrReturn(ppwszDst, VERR_INVALID_POINTER); 560 AssertPtrReturn(pcwDst, VERR_INVALID_POINTER); 561 562 /* Intermediate conversion to UTF-16. */ 563 size_t cwcTmp; 564 PRTUTF16 pwcTmp = NULL; 565 int rc = RTStrToUtf16Ex(pcSrc, cbSrc, &pwcTmp, 0, &cwcTmp); 566 if (RT_SUCCESS(rc)) 567 { 568 rc = ShClConvUtf16LFToCRLFA(pwcTmp, cwcTmp, ppwszDst, pcwDst); 569 RTUtf16Free(pwcTmp); 570 } 571 572 LogFlowFuncLeaveRC(rc); 573 return rc; 574 } 575 576 int ShClConvLatin1LFToUtf16CRLF(const char *pcSrc, unsigned cbSrc, 577 PRTUTF16 *ppwszDst, size_t *pcwDst) 578 { 579 AssertPtrReturn(pcSrc, VERR_INVALID_POINTER); 580 AssertReturn(cbSrc, VERR_INVALID_PARAMETER); 581 AssertPtrReturn(ppwszDst, VERR_INVALID_POINTER); 582 AssertPtrReturn(pcwDst, VERR_INVALID_POINTER); 583 584 int rc = VINF_SUCCESS; 585 586 PRTUTF16 pwszDst = NULL; 587 588 /* Calculate the space needed. */ 589 unsigned cbDst = 0; 590 for (unsigned i = 0; i < cbSrc && pcSrc[i] != '\0'; ++i) 591 { 592 if (pcSrc[i] == VBOX_SHCL_LINEFEED) 593 cbDst += sizeof(RTUTF16); 594 else 595 ++cbDst; 596 } 597 598 ++cbDst; /* Leave space for the terminator. */ 599 600 pwszDst = (PRTUTF16)RTMemAlloc(cbDst * sizeof(RTUTF16)); 601 if (!pwszDst) 602 rc = VERR_NO_MEMORY; 603 604 /* Do the conversion, bearing in mind that Latin-1 expands "naturally" to UTF-16. */ 605 if (RT_SUCCESS(rc)) 606 { 607 for (unsigned i = 0, j = 0; i < cbSrc; ++i, ++j) 608 { 609 if (pcSrc[i] != VBOX_SHCL_LINEFEED) 610 pwszDst[j] = pcSrc[i]; 611 else 612 { 613 pwszDst[j] = VBOX_SHCL_CARRIAGERETURN; 614 pwszDst[j + 1] = VBOX_SHCL_LINEFEED; 615 ++j; 616 } 617 } 618 619 pwszDst[cbDst - 1] = '\0'; /* Make sure we are zero-terminated. */ 620 } 621 622 if (RT_SUCCESS(rc)) 623 { 624 *ppwszDst = pwszDst; 625 *pcwDst = cbDst * sizeof(RTUTF16); 626 } 627 else 628 RTMemFree(pwszDst); 629 630 LogFlowFuncLeaveRC(rc); 631 return rc; 632 } 633 634 int ShClConvUtf16ToUtf8HTML(RTUTF16 *pwcSrc, size_t cwSrc, char **ppszDst, size_t *pcbDst) 635 { 636 AssertPtrReturn(pwcSrc, VERR_INVALID_POINTER); 637 AssertReturn (cwSrc, VERR_INVALID_PARAMETER); 638 AssertPtrReturn(ppszDst, VERR_INVALID_POINTER); 639 AssertPtrReturn(pcbDst, VERR_INVALID_POINTER); 640 641 int rc; 642 643 size_t cwTmp = cwSrc; 644 RTUTF16 *pwTmp = pwcSrc; 645 646 char *pchDst = NULL; 647 size_t cbDst = 0; 648 649 size_t i = 0; 650 while (i < cwTmp) 651 { 652 /* Find zero symbol (end of string). */ 653 for (; i < cwTmp && pwcSrc[i] != 0; i++) 654 ; 655 656 /* Convert found string. */ 657 char *psz = NULL; 658 size_t cch = 0; 659 rc = RTUtf16ToUtf8Ex(pwTmp, cwTmp, &psz, pwTmp - pwcSrc, &cch); 660 if (RT_FAILURE(rc)) 661 break; 662 663 /* Append new substring. */ 664 char *pchNew = (char *)RTMemRealloc(pchDst, cbDst + cch + 1); 665 if (!pchNew) 666 { 667 RTStrFree(psz); 668 rc = VERR_NO_MEMORY; 669 break; 670 } 671 672 pchDst = pchNew; 673 memcpy(pchDst + cbDst, psz, cch + 1); 674 675 RTStrFree(psz); 676 677 cbDst += cch + 1; 678 679 /* Skip zero symbols. */ 680 for (; i < cwTmp && pwcSrc[i] == 0; i++) 681 ; 682 683 /* Remember start of string. */ 684 pwTmp += i; 685 } 686 687 if (RT_SUCCESS(rc)) 688 { 689 *ppszDst = pchDst; 690 *pcbDst = cbDst; 691 471 692 return VINF_SUCCESS; 472 693 } 473 /** @todo convert the remainder of the Assert stuff to AssertLogRel. */ 474 /* We only take little endian Utf16 */ 475 if (pcwszSrc[0] == VBOX_SHCL_UTF16BEMARKER) 476 { 477 LogRel(("Shared Clipboard: vboxClipboardUtf16GetWinSize: received a big endian Utf16 string, returning VERR_INVALID_PARAMETER\n")); 478 AssertReturn(pcwszSrc[0] != VBOX_SHCL_UTF16BEMARKER, VERR_INVALID_PARAMETER); 479 } 480 cwDest = 0; 694 695 RTMemFree(pchDst); 696 697 LogFlowFuncLeaveRC(rc); 698 return rc; 699 } 700 701 int ShClUtf16LFLenUtf8(PCRTUTF16 pcwszSrc, size_t cwSrc, size_t *pchLen) 702 { 703 AssertPtrReturn(pcwszSrc, VERR_INVALID_POINTER); 704 AssertReturn(cwSrc, VERR_INVALID_PARAMETER); 705 AssertPtrReturn(pchLen, VERR_INVALID_POINTER); 706 707 AssertMsgReturn(pcwszSrc[0] != VBOX_SHCL_UTF16BEMARKER, 708 ("Big endian UTF-16 not supported yet\n"), VERR_NOT_SUPPORTED); 709 710 size_t cLen = 0; 711 712 /* Don't copy the endian marker. */ 713 size_t i = pcwszSrc[0] == VBOX_SHCL_UTF16LEMARKER ? 1 : 0; 714 481 715 /* Calculate the size of the destination text string. */ 482 716 /* Is this Utf16 or Utf16-LE? */ 483 for ( i = (pcwszSrc[0] == VBOX_SHCL_UTF16LEMARKER ? 1 : 0); i < cwSrc; ++i, ++cwDest)717 for (; i < cwSrc; ++i, ++cLen) 484 718 { 485 719 /* Check for a single line feed */ 486 720 if (pcwszSrc[i] == VBOX_SHCL_LINEFEED) 487 ++c wDest;721 ++cLen; 488 722 #ifdef RT_OS_DARWIN 489 723 /* Check for a single carriage return (MacOS) */ 490 724 if (pcwszSrc[i] == VBOX_SHCL_CARRIAGERETURN) 491 ++c wDest;725 ++cLen; 492 726 #endif 493 727 if (pcwszSrc[i] == 0) … … 497 731 } 498 732 } 499 /* Count the terminating null byte. */ 500 ++cwDest; 501 LogFlowFunc(("returning VINF_SUCCESS, %d 16bit words\n", cwDest)); 502 *pcwDest = cwDest; 733 734 /* Add terminator. */ 735 ++cLen; 736 737 *pchLen = cLen; 738 739 LogFlowFuncLeaveRC(VINF_SUCCESS); 503 740 return VINF_SUCCESS; 504 741 } 505 742 506 int ShClUtf16LinToWin(PCRTUTF16 pcwszSrc, size_t cwSrc, PRTUTF16 pu16Dest, size_t cwDest) 507 { 508 size_t i, j; 509 LogFlowFunc(("pcwszSrc=%.*ls, cwSrc=%u\n", cwSrc, pcwszSrc, cwSrc)); 510 if (!VALID_PTR(pcwszSrc) || !VALID_PTR(pu16Dest)) 511 { 512 LogRel(("Shared Clipboard: vboxClipboardUtf16LinToWin: received an invalid pointer, returning VERR_INVALID_PARAMETER\n")); 513 AssertReturn(VALID_PTR(pcwszSrc) && VALID_PTR(pu16Dest), VERR_INVALID_PARAMETER); 514 } 515 if (cwSrc == 0) 516 { 517 if (cwDest == 0) 518 { 519 LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n")); 520 return VERR_BUFFER_OVERFLOW; 521 } 522 pu16Dest[0] = 0; 523 LogFlowFunc(("empty source string, returning\n")); 524 return VINF_SUCCESS; 525 } 526 /* We only take little endian Utf16 */ 527 if (pcwszSrc[0] == VBOX_SHCL_UTF16BEMARKER) 528 { 529 LogRel(("Shared Clipboard: vboxClipboardUtf16LinToWin: received a big endian Utf16 string, returning VERR_INVALID_PARAMETER\n")); 530 AssertReturn(pcwszSrc[0] != VBOX_SHCL_UTF16BEMARKER, VERR_INVALID_PARAMETER); 531 } 743 int ShClUtf16CRLFLenUtf8(PCRTUTF16 pcwszSrc, size_t cwSrc, size_t *pchLen) 744 { 745 AssertPtrReturn(pcwszSrc, VERR_INVALID_POINTER); 746 AssertReturn(cwSrc, VERR_INVALID_PARAMETER); 747 AssertPtrReturn(pchLen, VERR_INVALID_POINTER); 748 749 AssertMsgReturn(pcwszSrc[0] != VBOX_SHCL_UTF16BEMARKER, 750 ("Big endian UTF-16 not supported yet\n"), VERR_NOT_SUPPORTED); 751 752 size_t cLen = 0; 753 754 /* Calculate the size of the destination text string. */ 755 /* Is this Utf16 or Utf16-LE? */ 756 if (pcwszSrc[0] == VBOX_SHCL_UTF16LEMARKER) 757 cLen = 0; 758 else 759 cLen = 1; 760 761 for (size_t i = 0; i < cwSrc; ++i, ++cLen) 762 { 763 if ( (i + 1 < cwSrc) 764 && (pcwszSrc[i] == VBOX_SHCL_CARRIAGERETURN) 765 && (pcwszSrc[i + 1] == VBOX_SHCL_LINEFEED)) 766 { 767 ++i; 768 } 769 if (pcwszSrc[i] == 0) 770 break; 771 } 772 773 /* Add terminating zero. */ 774 ++cLen; 775 776 *pchLen = cLen; 777 778 LogFlowFuncLeaveRC(VINF_SUCCESS); 779 return VINF_SUCCESS; 780 } 781 782 int ShClConvUtf16LFToCRLF(PCRTUTF16 pcwszSrc, size_t cwSrc, PRTUTF16 pu16Dst, size_t cwDst) 783 { 784 AssertPtrReturn(pcwszSrc, VERR_INVALID_POINTER); 785 AssertReturn(cwSrc, VERR_INVALID_PARAMETER); 786 AssertPtrReturn(pu16Dst, VERR_INVALID_POINTER); 787 AssertReturn(cwDst, VERR_INVALID_PARAMETER); 788 789 AssertMsgReturn(pcwszSrc[0] != VBOX_SHCL_UTF16BEMARKER, 790 ("Big endian UTF-16 not supported yet\n"), VERR_NOT_SUPPORTED); 791 792 int rc = VINF_SUCCESS; 793 532 794 /* Don't copy the endian marker. */ 533 for (i = (pcwszSrc[0] == VBOX_SHCL_UTF16LEMARKER ? 1 : 0), j = 0; i < cwSrc; ++i, ++j) 795 size_t i = pcwszSrc[0] == VBOX_SHCL_UTF16LEMARKER ? 1 : 0; 796 size_t j = 0; 797 798 for (; i < cwSrc; ++i, ++j) 534 799 { 535 800 /* Don't copy the null byte, as we add it below. */ 536 801 if (pcwszSrc[i] == 0) 537 802 break; 538 if (j == cwDest) 539 { 540 LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n")); 541 return VERR_BUFFER_OVERFLOW; 542 } 803 804 /* Not enough space in destination? */ 805 if (j == cwDst) 806 { 807 rc = VERR_BUFFER_OVERFLOW; 808 break; 809 } 810 543 811 if (pcwszSrc[i] == VBOX_SHCL_LINEFEED) 544 812 { 545 pu16D est[j] = VBOX_SHCL_CARRIAGERETURN;813 pu16Dst[j] = VBOX_SHCL_CARRIAGERETURN; 546 814 ++j; 547 if (j == cwDest) 815 816 /* Not enough space in destination? */ 817 if (j == cwDst) 548 818 { 549 LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n"));550 return VERR_BUFFER_OVERFLOW;819 rc = VERR_BUFFER_OVERFLOW; 820 break; 551 821 } 552 822 } … … 555 825 else if (pcwszSrc[i] == VBOX_SHCL_CARRIAGERETURN) 556 826 { 557 /* set cr */558 pu16D est[j] = VBOX_SHCL_CARRIAGERETURN;827 /* Set CR.r */ 828 pu16Dst[j] = VBOX_SHCL_CARRIAGERETURN; 559 829 ++j; 560 if (j == cwDest) 830 831 /* Not enough space in destination? */ 832 if (j == cwDst) 561 833 { 562 LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n"));563 return VERR_BUFFER_OVERFLOW;834 rc = VERR_BUFFER_OVERFLOW; 835 break; 564 836 } 565 /* add the lf */ 566 pu16Dest[j] = VBOX_SHCL_LINEFEED; 837 838 /* Add line feed. */ 839 pu16Dst[j] = VBOX_SHCL_LINEFEED; 567 840 continue; 568 841 } 569 842 #endif 570 pu16Dest[j] = pcwszSrc[i]; 571 } 572 /* Add the trailing null. */ 573 if (j == cwDest) 574 { 575 LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n")); 843 pu16Dst[j] = pcwszSrc[i]; 844 } 845 846 if (j == cwDst) 847 rc = VERR_BUFFER_OVERFLOW; 848 849 if (RT_SUCCESS(rc)) 850 { 851 /* Add terminator. */ 852 pu16Dst[j] = 0; 853 } 854 855 LogFlowFuncLeaveRC(rc); 856 return rc; 857 } 858 859 int ShClConvUtf16CRLFToLF(PCRTUTF16 pcwszSrc, size_t cwSrc, PRTUTF16 pu16Dst, size_t cwDst) 860 { 861 AssertPtrReturn(pcwszSrc, VERR_INVALID_POINTER); 862 AssertReturn(cwSrc, VERR_INVALID_PARAMETER); 863 AssertPtrReturn(pu16Dst, VERR_INVALID_POINTER); 864 AssertReturn(cwDst, VERR_INVALID_PARAMETER); 865 866 AssertMsgReturn(pcwszSrc[0] != VBOX_SHCL_UTF16BEMARKER, 867 ("Big endian UTF-16 not supported yet\n"), VERR_NOT_SUPPORTED); 868 869 /* Prepend the Utf16 byte order marker if it is missing. */ 870 size_t cwDstPos; 871 if (pcwszSrc[0] == VBOX_SHCL_UTF16LEMARKER) 872 { 873 cwDstPos = 0; 874 } 875 else 876 { 877 pu16Dst[0] = VBOX_SHCL_UTF16LEMARKER; 878 cwDstPos = 1; 879 } 880 881 for (size_t i = 0; i < cwSrc; ++i, ++cwDstPos) 882 { 883 if (pcwszSrc[i] == 0) 884 break; 885 886 if (cwDstPos == cwDst) 887 return VERR_BUFFER_OVERFLOW; 888 889 if ( (i + 1 < cwSrc) 890 && (pcwszSrc[i] == VBOX_SHCL_CARRIAGERETURN) 891 && (pcwszSrc[i + 1] == VBOX_SHCL_LINEFEED)) 892 { 893 ++i; 894 } 895 896 pu16Dst[cwDstPos] = pcwszSrc[i]; 897 } 898 899 if (cwDstPos == cwDst) 576 900 return VERR_BUFFER_OVERFLOW; 577 } 578 pu16Dest[j] = 0; 579 LogFlowFunc(("rc=VINF_SUCCESS, pu16Dest=%ls\n", pu16Dest)); 901 902 /* Add terminating zero. */ 903 pu16Dst[cwDstPos] = 0; 904 905 LogFlowFuncLeaveRC(VINF_SUCCESS); 580 906 return VINF_SUCCESS; 581 907 } 582 908 583 int ShClUtf16GetLinSize(PCRTUTF16 pcwszSrc, size_t cwSrc, size_t *pcwDest)584 {585 size_t cwDest;586 587 LogFlowFunc(("pcwszSrc=%.*ls, cwSrc=%u\n", cwSrc, pcwszSrc, cwSrc));588 if (!VALID_PTR(pcwszSrc))589 {590 LogRel(("Shared Clipboard: vboxClipboardUtf16GetLinSize: received an invalid Utf16 string, returning VERR_INVALID_PARAMETER\n"));591 AssertReturn(VALID_PTR(pcwszSrc), VERR_INVALID_PARAMETER);592 }593 if (cwSrc == 0)594 {595 LogFlowFunc(("empty source string, returning VINF_SUCCESS\n"));596 *pcwDest = 0;597 return VINF_SUCCESS;598 }599 /* We only take little endian Utf16 */600 if (pcwszSrc[0] == VBOX_SHCL_UTF16BEMARKER)601 {602 LogRel(("Shared Clipboard: vboxClipboardUtf16GetLinSize: received a big endian Utf16 string, returning VERR_INVALID_PARAMETER\n"));603 AssertReturn(pcwszSrc[0] != VBOX_SHCL_UTF16BEMARKER, VERR_INVALID_PARAMETER);604 }605 /* Calculate the size of the destination text string. */606 /* Is this Utf16 or Utf16-LE? */607 if (pcwszSrc[0] == VBOX_SHCL_UTF16LEMARKER)608 cwDest = 0;609 else610 cwDest = 1;611 for (size_t i = 0; i < cwSrc; ++i, ++cwDest)612 {613 if ( (i + 1 < cwSrc)614 && (pcwszSrc[i] == VBOX_SHCL_CARRIAGERETURN)615 && (pcwszSrc[i + 1] == VBOX_SHCL_LINEFEED))616 {617 ++i;618 }619 if (pcwszSrc[i] == 0)620 {621 break;622 }623 }624 /* Terminating zero */625 ++cwDest;626 LogFlowFunc(("returning %d\n", cwDest));627 *pcwDest = cwDest;628 return VINF_SUCCESS;629 }630 631 int ShClUtf16WinToLin(PCRTUTF16 pcwszSrc, size_t cwSrc, PRTUTF16 pu16Dest, size_t cwDest)632 {633 size_t cwDestPos;634 635 LogFlowFunc(("pcwszSrc=%.*ls, cwSrc=%u, pu16Dest=%p, cwDest=%u\n",636 cwSrc, pcwszSrc, cwSrc, pu16Dest, cwDest));637 /* A buffer of size 0 may not be an error, but it is not a good idea either. */638 Assert(cwDest > 0);639 if (!VALID_PTR(pcwszSrc) || !VALID_PTR(pu16Dest))640 {641 LogRel(("Shared Clipboard: vboxClipboardUtf16WinToLin: received an invalid pointer, returning VERR_INVALID_PARAMETER\n"));642 AssertReturn(VALID_PTR(pcwszSrc) && VALID_PTR(pu16Dest), VERR_INVALID_PARAMETER);643 }644 /* We only take little endian Utf16 */645 if (pcwszSrc[0] == VBOX_SHCL_UTF16BEMARKER)646 {647 LogRel(("Shared Clipboard: vboxClipboardUtf16WinToLin: received a big endian Utf16 string, returning VERR_INVALID_PARAMETER\n"));648 AssertMsgFailedReturn(("received a big endian string\n"), VERR_INVALID_PARAMETER);649 }650 if (cwDest == 0)651 {652 LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n"));653 return VERR_BUFFER_OVERFLOW;654 }655 if (cwSrc == 0)656 {657 pu16Dest[0] = 0;658 LogFlowFunc(("received empty string. Returning VINF_SUCCESS\n"));659 return VINF_SUCCESS;660 }661 /* Prepend the Utf16 byte order marker if it is missing. */662 if (pcwszSrc[0] == VBOX_SHCL_UTF16LEMARKER)663 {664 cwDestPos = 0;665 }666 else667 {668 pu16Dest[0] = VBOX_SHCL_UTF16LEMARKER;669 cwDestPos = 1;670 }671 for (size_t i = 0; i < cwSrc; ++i, ++cwDestPos)672 {673 if (pcwszSrc[i] == 0)674 {675 break;676 }677 if (cwDestPos == cwDest)678 {679 LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n"));680 return VERR_BUFFER_OVERFLOW;681 }682 if ( (i + 1 < cwSrc)683 && (pcwszSrc[i] == VBOX_SHCL_CARRIAGERETURN)684 && (pcwszSrc[i + 1] == VBOX_SHCL_LINEFEED))685 {686 ++i;687 }688 pu16Dest[cwDestPos] = pcwszSrc[i];689 }690 /* Terminating zero */691 if (cwDestPos == cwDest)692 {693 LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n"));694 return VERR_BUFFER_OVERFLOW;695 }696 pu16Dest[cwDestPos] = 0;697 LogFlowFunc(("set string %ls. Returning\n", pu16Dest + 1));698 return VINF_SUCCESS;699 }700 701 909 int ShClDibToBmp(const void *pvSrc, size_t cbSrc, void **ppvDest, size_t *pcbDest) 702 910 { 703 size_t cb = sizeof(BMFILEHEADER) + cbSrc; 704 PBMFILEHEADER pFileHeader = NULL; 705 void *pvDest = NULL; 706 size_t offPixel = 0; 707 708 AssertPtrReturn(pvSrc, VERR_INVALID_PARAMETER); 709 AssertPtrReturn(ppvDest, VERR_INVALID_PARAMETER); 710 AssertPtrReturn(pcbDest, VERR_INVALID_PARAMETER); 911 AssertPtrReturn(pvSrc, VERR_INVALID_POINTER); 912 AssertReturn(cbSrc, VERR_INVALID_PARAMETER); 913 AssertPtrReturn(ppvDest, VERR_INVALID_POINTER); 914 AssertPtrReturn(pcbDest, VERR_INVALID_POINTER); 711 915 712 916 PBMINFOHEADER pBitmapInfoHeader = (PBMINFOHEADER)pvSrc; … … 716 920 || RT_LE2H_U32(pBitmapInfoHeader->uSize) != sizeof(BMINFOHEADER)) 717 921 { 718 Log(("vboxClipboardDibToBmp: invalid or unsupported bitmap data\n"));719 922 return VERR_INVALID_PARAMETER; 720 923 } 721 924 722 offPixel = sizeof(BMFILEHEADER)723 + RT_LE2H_U32(pBitmapInfoHeader->uSize)724 + RT_LE2H_U32(pBitmapInfoHeader->uClrUsed) * sizeof(uint32_t);925 size_t offPixel = sizeof(BMFILEHEADER) 926 + RT_LE2H_U32(pBitmapInfoHeader->uSize) 927 + RT_LE2H_U32(pBitmapInfoHeader->uClrUsed) * sizeof(uint32_t); 725 928 if (cbSrc < offPixel) 726 {727 Log(("vboxClipboardDibToBmp: invalid bitmap data\n"));728 929 return VERR_INVALID_PARAMETER; 729 } 730 731 pvDest = RTMemAlloc(cb); 930 931 size_t cbDst = sizeof(BMFILEHEADER) + cbSrc; 932 933 void *pvDest = RTMemAlloc(cbDst); 732 934 if (!pvDest) 733 {734 Log(("writeToPasteboard: cannot allocate memory for bitmap\n"));735 935 return VERR_NO_MEMORY; 736 } 737 738 pFileHeader = (PBMFILEHEADER)pvDest; 936 937 PBMFILEHEADER pFileHeader = (PBMFILEHEADER)pvDest; 938 739 939 pFileHeader->uType = BITMAPHEADERMAGIC; 740 pFileHeader->uSize = (uint32_t)RT_H2LE_U32(cb );940 pFileHeader->uSize = (uint32_t)RT_H2LE_U32(cbDst); 741 941 pFileHeader->uReserved1 = pFileHeader->uReserved2 = 0; 742 942 pFileHeader->uOffBits = (uint32_t)RT_H2LE_U32(offPixel); 943 743 944 memcpy((uint8_t *)pvDest + sizeof(BMFILEHEADER), pvSrc, cbSrc); 945 744 946 *ppvDest = pvDest; 745 *pcbDest = cb; 947 *pcbDest = cbDst; 948 949 LogFlowFuncLeaveRC(VINF_SUCCESS); 746 950 return VINF_SUCCESS; 747 951 } … … 749 953 int ShClBmpGetDib(const void *pvSrc, size_t cbSrc, const void **ppvDest, size_t *pcbDest) 750 954 { 751 AssertPtrReturn(pvSrc, VERR_INVALID_PARAMETER); 752 AssertPtrReturn(ppvDest, VERR_INVALID_PARAMETER); 753 AssertPtrReturn(pcbDest, VERR_INVALID_PARAMETER); 955 AssertPtrReturn(pvSrc, VERR_INVALID_POINTER); 956 AssertReturn(cbSrc, VERR_INVALID_PARAMETER); 957 AssertPtrReturn(ppvDest, VERR_INVALID_POINTER); 958 AssertPtrReturn(pcbDest, VERR_INVALID_POINTER); 754 959 755 960 PBMFILEHEADER pFileHeader = (PBMFILEHEADER)pvSrc; … … 758 963 || RT_LE2H_U32(pFileHeader->uSize) != cbSrc) 759 964 { 760 Log(("vboxClipboardBmpGetDib: invalid bitmap data\n"));761 965 return VERR_INVALID_PARAMETER; 762 966 } … … 764 968 *ppvDest = ((uint8_t *)pvSrc) + sizeof(BMFILEHEADER); 765 969 *pcbDest = cbSrc - sizeof(BMFILEHEADER); 970 766 971 return VINF_SUCCESS; 767 972 } -
trunk/src/VBox/GuestHost/SharedClipboard/clipboard-x11.cpp
r85799 r85828 707 707 708 708 Atom *pAtoms = (Atom *)pValue; 709 unsigned i, j;710 709 711 710 LogFlowFunc(("pValue=%p, *pcLen=%u, *atomType=%d%s\n", 712 711 pValue, *pcLen, *atomType, *atomType == XT_CONVERT_FAIL ? " (XT_CONVERT_FAIL)" : "")); 713 712 713 unsigned cFormats = *pcLen; 714 715 LogRel2(("Shared Clipboard: %u formats were found\n", cFormats)); 716 714 717 SHCLX11FMTIDX *pFormats = NULL; 715 if ( *pcLen718 if ( cFormats 716 719 && pValue 717 720 && (*atomType != XT_CONVERT_FAIL /* time out */)) 718 721 { 719 pFormats = (SHCLX11FMTIDX *)RTMemAllocZ(*pcLen * sizeof(SHCLX11FMTIDX)); 722 /* Allocated array to hold the format indices. */ 723 pFormats = (SHCLX11FMTIDX *)RTMemAllocZ(cFormats * sizeof(SHCLX11FMTIDX)); 720 724 } 721 725 … … 723 727 if (pValue) 724 728 { 725 for ( i = 0; i < *pcLen; ++i)729 for (unsigned i = 0; i < cFormats; ++i) 726 730 { 727 731 if (pAtoms[i]) … … 739 743 if (pFormats) 740 744 { 741 for ( i = 0; i < *pcLen; ++i)742 { 743 for ( j = 0; j < RT_ELEMENTS(g_aFormats); ++j)745 for (unsigned i = 0; i < cFormats; ++i) 746 { 747 for (unsigned j = 0; j < RT_ELEMENTS(g_aFormats); ++j) 744 748 { 745 749 Atom target = XInternAtom(XtDisplay(widget), … … 748 752 pFormats[i] = j; 749 753 } 750 #if defined(DEBUG) &&!defined(TESTCASE)751 LogRel2(("%s: reporting format %d (%s)\n", __FUNCTION__,752 pFormats[i], g_aFormats[pFormats[i]].pcszAtom));754 #if !defined(TESTCASE) 755 if (pFormats[i] != SHCLX11FMT_INVALID) 756 LogRel2(("Shared Clipboard: Reporting format '%s'\n", g_aFormats[pFormats[i]].pcszAtom)); 753 757 #endif 754 758 } … … 757 761 LogFunc(("Reporting empty targets (none reported or allocation failure)\n")); 758 762 759 clipUpdateX11Targets(pCtx, pFormats, *pcLen);763 clipUpdateX11Targets(pCtx, pFormats, cFormats); 760 764 RTMemFree(pFormats); 761 765 … … 1307 1311 1308 1312 /** 1309 * Calculates a buffer size large enough to hold the source Windows format 1310 * text converted into Unix Utf8, including the null terminator. 1311 * 1312 * @returns VBox status code. 1313 * @param pwsz The source text in UCS-2 with Windows EOLs. 1314 * @param cwc The size in USC-2 elements of the source text, with or 1315 * without the terminator. 1316 * @param pcbActual Where to store the buffer size needed. 1317 */ 1318 static int clipWinTxtBufSizeForUtf8(PRTUTF16 pwsz, size_t cwc, 1319 size_t *pcbActual) 1320 { 1321 size_t cbRet = 0; 1322 int rc = RTUtf16CalcUtf8LenEx(pwsz, cwc, &cbRet); 1323 if (RT_SUCCESS(rc)) 1324 *pcbActual = cbRet + 1; /* null terminator */ 1325 return rc; 1326 } 1327 1328 /** 1329 * Converts text from Windows format (UCS-2 with CRLF line endings) to standard UTF-8. 1330 * 1331 * @returns VBox status code. 1332 * @param pwszSrc The text to be converted. 1333 * @param cbSrc The length of @a pwszSrc in bytes. 1334 * @param pszBuf Where to write the converted string. 1335 * @param cbBuf The size of the buffer pointed to by @a pszBuf. 1336 * @param pcbActual Where to store the size of the converted string. 1337 * optional. 1338 */ 1339 static int clipWinTxtToUtf8(PRTUTF16 pwszSrc, size_t cbSrc, char *pszBuf, 1340 size_t cbBuf, size_t *pcbActual) 1341 { 1342 PRTUTF16 pwszTmp = NULL; 1343 size_t cwSrc = cbSrc / 2, cwTmp = 0, cbDest = 0; 1344 int rc = VINF_SUCCESS; 1345 1346 LogFlowFunc (("pwszSrc=%.*ls, cbSrc=%u\n", cbSrc, pwszSrc, cbSrc)); 1347 /* How long will the converted text be? */ 1348 AssertPtr(pwszSrc); 1349 AssertPtr(pszBuf); 1350 rc = ShClUtf16GetLinSize(pwszSrc, cwSrc, &cwTmp); 1351 if (RT_SUCCESS(rc) && cwTmp == 0) 1352 rc = VERR_NO_DATA; 1353 if (RT_SUCCESS(rc)) 1354 pwszTmp = (PRTUTF16)RTMemAlloc(cwTmp * 2); 1355 if (!pwszTmp) 1356 rc = VERR_NO_MEMORY; 1357 /* Convert the text. */ 1358 if (RT_SUCCESS(rc)) 1359 rc = ShClUtf16WinToLin(pwszSrc, cwSrc, pwszTmp, cwTmp); 1360 if (RT_SUCCESS(rc)) 1361 { 1362 /* Convert the UTF-16 string to Utf8. */ 1363 rc = RTUtf16ToUtf8Ex(pwszTmp + 1, cwTmp - 1, &pszBuf, cbBuf, 1364 &cbDest); 1365 } 1366 RTMemFree(reinterpret_cast<void *>(pwszTmp)); 1367 if (pcbActual) 1368 *pcbActual = cbDest + 1; 1369 1370 if (RT_SUCCESS(rc)) 1371 LogFlowFunc (("converted string is %.*s. Returning.\n", cbDest, pszBuf)); 1372 1373 LogFlowFuncLeaveRC(rc); 1374 return rc; 1375 } 1376 1377 /** 1378 * Satisfies a request from X11 to convert the clipboard text to UTF-8. We 1379 * return null-terminated text, but can cope with non-null-terminated input. 1380 * 1381 * @returns VBox status code. 1313 * Satisfies a request from X11 to convert the clipboard text to UTF-8 LF. 1314 * 1315 * @returns VBox status code. VERR_NO_DATA if no data was converted. 1382 1316 * @param pDisplay An X11 display structure, needed for conversions 1383 1317 * performed by Xlib. … … 1395 1329 * data we are returning. 1396 1330 */ 1397 static int clipWinTxtToUtf8ForX11CB(Display *pDisplay, PRTUTF16 pwszSrc, 1398 size_t cbSrc, Atom *atomTarget, 1399 Atom *atomTypeReturn, 1400 XtPointer *pValReturn, 1401 unsigned long *pcLenReturn, 1402 int *piFormatReturn) 1403 { 1404 RT_NOREF(pDisplay, pcLenReturn); 1331 static int clipUtf16CRLFToUtf8LF(Display *pDisplay, PRTUTF16 pwszSrc, 1332 size_t cbSrc, Atom *atomTarget, 1333 Atom *atomTypeReturn, 1334 XtPointer *pValReturn, 1335 unsigned long *pcLenReturn, 1336 int *piFormatReturn) 1337 { 1338 RT_NOREF(pDisplay); 1339 1340 const size_t cwcSrc = cbSrc / sizeof(RTUTF16); 1341 if (!cwcSrc) 1342 return VERR_NO_DATA; 1405 1343 1406 1344 /* This may slightly overestimate the space needed. */ 1407 size_t c bDest = 0;1408 int rc = clipWinTxtBufSizeForUtf8(pwszSrc, cbSrc / 2, &cbDest);1345 size_t chDst = 0; 1346 int rc = ShClUtf16LenUtf8(pwszSrc, cwcSrc, &chDst); 1409 1347 if (RT_SUCCESS(rc)) 1410 1348 { 1411 char *pszDest = (char *)XtMalloc(c bDest);1349 char *pszDest = (char *)XtMalloc(chDst); 1412 1350 size_t cbActual = 0; 1413 1351 if (pszDest) 1414 1352 { 1415 rc = clipWinTxtToUtf8(pwszSrc, cbSrc, pszDest, cbDest, &cbActual);1353 rc = ShClConvUtf16CRLFToUtf8LF(pwszSrc, cwcSrc, pszDest, chDst, &cbActual); 1416 1354 } 1417 1355 else … … 1421 1359 { 1422 1360 *atomTypeReturn = *atomTarget; 1423 *pValReturn = (XtPointer)pszDest;1424 *pcLenReturn = cbActual;1361 *pValReturn = (XtPointer)pszDest; 1362 *pcLenReturn = cbActual; 1425 1363 *piFormatReturn = 8; 1426 1364 } 1427 1365 } 1366 1367 LogFlowFuncLeaveRC(rc); 1428 1368 return rc; 1429 1369 } … … 1527 1467 rc = VERR_NO_DATA; 1528 1468 if (RT_SUCCESS(rc) && ((clipFormat == SHCLX11FMT_UTF8) || (clipFormat == SHCLX11FMT_TEXT))) 1529 rc = clip WinTxtToUtf8ForX11CB(XtDisplay(pCtx->pWidget),1530 1531 1532 1469 rc = clipUtf16CRLFToUtf8LF(XtDisplay(pCtx->pWidget), 1470 (PRTUTF16)pv, cb, atomTarget, 1471 atomTypeReturn, pValReturn, 1472 pcLenReturn, piFormatReturn); 1533 1473 if (RT_SUCCESS(rc)) 1534 1474 clipTrimTrailingNul(*(XtPointer *)pValReturn, pcLenReturn, clipFormat); … … 1769 1709 1770 1710 /** 1771 * Massages generic UTF-16 with CR end-of-lines into the format Windows expects1772 * and return the result in a RTMemAlloc allocated buffer.1773 *1774 * @returns VBox status code.1775 * @param pwcSrc The source as UTF-16.1776 * @param cwcSrc The number of 16bit elements in @a pwcSrc, not counting1777 * the terminating zero.1778 * @param ppwszDest Where to store the buffer address.1779 * @param pcbDest On success, where to store the number of bytes written.1780 * Undefined otherwise. Optional.1781 */1782 static int clipUtf16ToWinTxt(RTUTF16 *pwcSrc, size_t cwcSrc,1783 PRTUTF16 *ppwszDest, uint32_t *pcbDest)1784 {1785 AssertPtrReturn(pwcSrc, VERR_INVALID_POINTER);1786 AssertPtrReturn(ppwszDest, VERR_INVALID_POINTER);1787 1788 LogFlowFunc(("pwcSrc=%p, cwcSrc=%u, ppwszDest=%p\n", pwcSrc, cwcSrc, ppwszDest));1789 1790 if (pcbDest)1791 *pcbDest = 0;1792 1793 PRTUTF16 pwszDest = NULL;1794 size_t cwcDest;1795 int rc = ShClUtf16GetWinSize(pwcSrc, cwcSrc + 1, &cwcDest);1796 if (RT_SUCCESS(rc))1797 {1798 pwszDest = (PRTUTF16)RTMemAlloc(cwcDest * sizeof(RTUTF16));1799 if (!pwszDest)1800 rc = VERR_NO_MEMORY;1801 }1802 1803 if (RT_SUCCESS(rc))1804 rc = ShClUtf16LinToWin(pwcSrc, cwcSrc + 1, pwszDest, cwcDest);1805 1806 if (RT_SUCCESS(rc))1807 {1808 LogFlowFunc(("Converted string is %.*ls\n", cwcDest, pwszDest));1809 1810 *ppwszDest = pwszDest;1811 1812 if (pcbDest)1813 *pcbDest = cwcDest * sizeof(RTUTF16);1814 }1815 else1816 RTMemFree(pwszDest);1817 1818 LogFlowFuncLeaveRC(rc);1819 return rc;1820 }1821 1822 /**1823 * Converts UTF-8 text with CR end-of-lines into UTF-16 as Windows expects it1824 * and return the result in a RTMemAlloc allocated buffer.1825 *1826 * @returns VBox status code.1827 * @param pcSrc The source UTF-8.1828 * @param cbSrc The size of the source in bytes, not counting the1829 * terminating zero.1830 * @param ppwszDest Where to store the buffer address.1831 * @param pcbDest On success, where to store the number of bytes written.1832 * Undefined otherwise. Optional.1833 */1834 static int clipUtf8ToWinTxt(const char *pcSrc, unsigned cbSrc,1835 PRTUTF16 *ppwszDest, uint32_t *pcbDest)1836 {1837 AssertPtrReturn(pcSrc, VERR_INVALID_POINTER);1838 AssertPtrReturn(ppwszDest, VERR_INVALID_POINTER);1839 1840 LogFlowFunc(("pcSrc=%p, cbSrc=%u, ppwszDest=%p\n", pcSrc, cbSrc, ppwszDest));1841 1842 if (pcbDest)1843 *pcbDest = 0;1844 1845 /* Intermediate conversion to UTF-16. */1846 size_t cwcTmp;1847 PRTUTF16 pwcTmp = NULL;1848 int rc = RTStrToUtf16Ex(pcSrc, cbSrc, &pwcTmp, 0, &cwcTmp);1849 if (RT_SUCCESS(rc))1850 rc = clipUtf16ToWinTxt(pwcTmp, cwcTmp, ppwszDest, pcbDest);1851 1852 RTUtf16Free(pwcTmp);1853 1854 LogFlowFuncLeaveRC(rc);1855 return rc;1856 }1857 1858 /**1859 * Converts Latin-1 text with CR end-of-lines into UTF-16 as Windows expects1860 * it and return the result in a RTMemAlloc allocated buffer.1861 *1862 * @returns VBox status code.1863 * @param pcSrc The source text.1864 * @param cbSrc The size of the source in bytes, not counting the1865 * terminating zero.1866 * @param ppwszDest Where to store the buffer address.1867 * @param pcbDest On success, where to store the number of bytes written.1868 * Undefined otherwise. Optional.1869 */1870 static int clipLatin1ToWinTxt(char *pcSrc, unsigned cbSrc,1871 PRTUTF16 *ppwszDest, uint32_t *pcbDest)1872 {1873 AssertPtrReturn(pcSrc, VERR_INVALID_POINTER);1874 AssertPtrReturn(ppwszDest, VERR_INVALID_POINTER);1875 1876 LogFlowFunc(("pcSrc=%.*s, cbSrc=%u, ppwszDest=%p\n", cbSrc, (char *) pcSrc, cbSrc, ppwszDest));1877 1878 PRTUTF16 pwszDest = NULL;1879 int rc = VINF_SUCCESS;1880 1881 /* Calculate the space needed. */1882 unsigned cwcDest = 0;1883 for (unsigned i = 0; i < cbSrc && pcSrc[i] != '\0'; ++i)1884 {1885 if (pcSrc[i] == VBOX_SHCL_LINEFEED)1886 cwcDest += 2;1887 else1888 ++cwcDest;1889 }1890 1891 ++cwcDest; /* Leave space for the terminator. */1892 1893 if (pcbDest)1894 *pcbDest = cwcDest * sizeof(RTUTF16);1895 1896 pwszDest = (PRTUTF16) RTMemAlloc(cwcDest * sizeof(RTUTF16));1897 if (!pwszDest)1898 rc = VERR_NO_MEMORY;1899 1900 /* And do the conversion, bearing in mind that Latin-1 expands "naturally"1901 * to UTF-16. */1902 if (RT_SUCCESS(rc))1903 {1904 for (unsigned i = 0, j = 0; i < cbSrc; ++i, ++j)1905 {1906 if (pcSrc[i] != VBOX_SHCL_LINEFEED)1907 pwszDest[j] = pcSrc[i];1908 else1909 {1910 pwszDest[j] = VBOX_SHCL_CARRIAGERETURN;1911 pwszDest[j + 1] = VBOX_SHCL_LINEFEED;1912 ++j;1913 }1914 }1915 1916 pwszDest[cwcDest - 1] = '\0'; /* Make sure we are zero-terminated. */1917 1918 LogFlowFunc(("Converted text is %.*ls\n", cwcDest, pwszDest));1919 }1920 1921 if (RT_SUCCESS(rc))1922 {1923 *ppwszDest = pwszDest;1924 }1925 else1926 RTMemFree(pwszDest);1927 1928 LogFlowFuncLeaveRC(rc);1929 return rc;1930 }1931 1932 /**1933 * Converts UTF-16 text into UTF-8 as Windows expects1934 * it and return the result in a RTMemAlloc allocated buffer.1935 *1936 * @returns VBox status code.1937 * @param pcSrc The source text.1938 * @param cbSrc The size of the source in bytes, not counting the1939 * terminating zero.1940 * @param ppwszDest Where to store the buffer address.1941 * @param pcbDest On success, where to store the number of bytes written.1942 * Undefined otherwise. Optional.1943 */1944 static int clipUTF16ToWinHTML(RTUTF16 *pwcBuf, size_t cb, char **ppszOut, uint32_t *pcOut)1945 {1946 AssertPtrReturn(pwcBuf, VERR_INVALID_POINTER);1947 AssertReturn (cb, VERR_INVALID_PARAMETER);1948 AssertPtrReturn(ppszOut, VERR_INVALID_POINTER);1949 AssertPtrReturn(pcOut, VERR_INVALID_POINTER);1950 1951 if (cb % 2)1952 return VERR_INVALID_PARAMETER;1953 1954 size_t cwc = cb / 2;1955 size_t i = 0;1956 RTUTF16 *pwc = pwcBuf;1957 char *pchRes = NULL;1958 size_t cRes = 0;1959 LogFlowFunc(("src= %ls cb=%d i=%i, %x %x\n", pwcBuf, cb, i, ppszOut, pcOut));1960 while (i < cwc)1961 {1962 /* find zero symbol (end of string) */1963 for (; i < cwc && pwcBuf[i] != 0; i++)1964 ;1965 LogFlowFunc(("skipped nulls i=%d cwc=%d\n", i, cwc));1966 1967 /* convert found string */1968 char *psz = NULL;1969 size_t cch = 0;1970 int rc = RTUtf16ToUtf8Ex(pwc, cwc, &psz, pwc - pwcBuf, &cch);1971 LogFlowFunc(("utf16toutf8 src= %ls res=%s i=%i\n", pwc, psz, i));1972 if (RT_FAILURE(rc))1973 {1974 RTMemFree(pchRes);1975 return rc;1976 }1977 1978 /* append new substring */1979 char *pchNew = (char *)RTMemRealloc(pchRes, cRes + cch + 1);1980 if (!pchNew)1981 {1982 RTMemFree(pchRes);1983 RTStrFree(psz);1984 return VERR_NO_MEMORY;1985 }1986 pchRes = pchNew;1987 memcpy(pchRes + cRes, psz, cch + 1);1988 LogFlowFunc(("Temp result res=%s\n", pchRes + cRes));1989 1990 /* remove temporary buffer */1991 RTStrFree(psz);1992 cRes += cch + 1;1993 /* skip zero symbols */1994 for (; i < cwc && pwcBuf[i] == 0; i++)1995 ;1996 /* remember start of string */1997 pwc += i;1998 }1999 *ppszOut = pchRes;2000 *pcOut = cRes;2001 2002 return VINF_SUCCESS;2003 }2004 2005 /**2006 1711 * Converts the data obtained from the X11 clipboard to the required format, 2007 1712 * place it in the buffer supplied and signal that data has arrived. … … 2024 1729 int rc = VINF_SUCCESS; 2025 1730 2026 void 2027 uint32_t cbDst = 0;1731 void *pvDst = NULL; 1732 size_t cbDst = 0; 2028 1733 2029 1734 if (pvSrc == NULL) … … 2041 1746 case SHCLX11FMT_TEXT: 2042 1747 { 2043 /* If we are given broken UTF-8, we treat it as Latin1. */ /** @todo Is this acceptable? */ 1748 size_t cwDst; 1749 1750 /* If we are given broken UTF-8, we treat it as Latin1. */ /** @todo BUGBUG Is this acceptable? */ 2044 1751 if (RT_SUCCESS(RTStrValidateEncodingEx((char *)pvSrc, cbSrc, 0))) 1752 rc = ShClConvUtf8LFToUtf16CRLF((const char *)pvSrc, cbSrc, 1753 (PRTUTF16 *)&pvDst, &cwDst); 1754 else 1755 rc = ShClConvLatin1LFToUtf16CRLF((char *)pvSrc, cbSrc, 1756 (PRTUTF16 *)&pvDst, &cbDst); 1757 if (RT_SUCCESS(rc)) 2045 1758 { 2046 rc = clipUtf8ToWinTxt((const char *)pvSrc, cbSrc, 2047 (PRTUTF16 *)&pvDst, &cbDst); 2048 } 2049 else 2050 { 2051 rc = clipLatin1ToWinTxt((char *)pvSrc, cbSrc, 2052 (PRTUTF16 *)&pvDst, &cbDst); 1759 AssertBreakStmt(cwDst, rc = VERR_INVALID_PARAMETER); 1760 cbDst = cwDst * sizeof(RTUTF16); /* Convert RTUTF16 units to bytes. */ 2053 1761 } 2054 1762 break; … … 2113 1821 * Some applications sends data in UTF-16, some in UTF-8, 2114 1822 * without indication it in MIME. 2115 * But in case of UTF-16, at least an OpenOffice adds Byte Order Mark - 0xfeff 2116 * at start of clipboard data. 1823 * 1824 * In case of UTF-16, at least [Open|Libre] Office adds an byte order mark (0xfeff) 1825 * at the start of the clipboard data. 2117 1826 */ 2118 1827 if ( cbSrc >= sizeof(RTUTF16) 2119 && *(PRTUTF16)pvSrc == 0xfeff)1828 && *(PRTUTF16)pvSrc == VBOX_SHCL_UTF16LEMARKER) 2120 1829 { 2121 LogFlowFunc((" \n")); 2122 rc = clipUTF16ToWinHTML((RTUTF16 *)pvSrc, cbSrc, 2123 (char**)&pvDst, &cbDst); 1830 rc = ShClConvUtf16ToUtf8HTML((PRTUTF16)pvSrc, cbSrc / sizeof(RTUTF16), (char**)&pvDst, &cbDst); 1831 if (RT_SUCCESS(rc)) 1832 { 1833 LogFlowFunc(("UTF-16 Unicode source (%u bytes):\n%ls\n\n", cbSrc, pvSrc)); 1834 LogFlowFunc(("Byte Order Mark = %hx", ((PRTUTF16)pvSrc)[0])); 1835 LogFlowFunc(("UTF-8 Unicode dest (%u bytes):\n%s\n\n", cbDst, pvDst)); 1836 } 1837 else 1838 LogRel(("Shared Clipboard: Converting UTF-16 Unicode failed with %Rrc\n", rc)); 2124 1839 } 2125 else 1840 else /* Raw data. */ 2126 1841 { 2127 1842 pvDst = RTMemAlloc(cbSrc); … … 2138 1853 } 2139 1854 2140 LogFlowFunc(("Source unicode %ls, cbSrc = %d\n, Byte Order Mark = %hx", pvSrc, cbSrc, ((PRTUTF16)pvSrc)[0]));2141 LogFlowFunc(("converted to win unicode %s, cbDest = %d, rc = %Rrc\n", pvDst, cbDst, rc));2142 1855 rc = VINF_SUCCESS; 2143 1856 break;
Note:
See TracChangeset
for help on using the changeset viewer.