From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1955) id D7CAC385840D; Wed, 3 Nov 2021 10:05:31 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D7CAC385840D To: cygwin-apps-cvs@sourceware.org Subject: [cygutils - Chuck Wilson's collection of Cygwin utilities] branch master, updated. v1_4_16-9-g6a2162a X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Oldrev: 936dce44b5799e3fd6926b9faacd9046cf5f2aaa X-Git-Newrev: 6a2162acab2e93a6fe9bf90907aa6656f084d19f Message-Id: <20211103100531.D7CAC385840D@sourceware.org> Date: Wed, 3 Nov 2021 10:05:31 +0000 (GMT) From: Mark Geisert X-BeenThere: cygwin-apps-cvs@cygwin.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Cygwin-apps git logs List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Nov 2021 10:05:32 -0000 https://sourceware.org/git/gitweb.cgi?p=cygwin-apps/cygutils.git;h=6a2162acab2e93a6fe9bf90907aa6656f084d19f commit 6a2162acab2e93a6fe9bf90907aa6656f084d19f Author: Mark Geisert Date: Wed Nov 3 03:05:24 2021 -0700 Update to released 1.4.16-8 content Diff: --- ChangeLog | 8 +++ NEWS | 1 + src/clip/getclip.c | 88 +++++++++++++---------- src/clip/putclip.c | 206 ++++++++++++++++++++++++----------------------------- 4 files changed, 150 insertions(+), 153 deletions(-) diff --git a/ChangeLog b/ChangeLog index 921b9d0..98e8d40 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2021-11-03 Mark Geisert (1.4.16-8) + + * src/clip/{get,put}clip.c: Replace use of Windows UTF-8 conversion + functions with corresponding POSIX functions. MultiByteToWideChar-> + mbstowcs, WideCharToMultiByte->wcstombs. Thanks to Takashi Yano. + * src/putclip.c: Have putclip open the clipboard just once instead + of multiple times for multiple formats. Thanks to Takashi Yano. + 2021-09-23 Mark Geisert (1.4.16-7) * src/readshortcut/readshortcut.c: Fix mbstowcs usage so no chance diff --git a/NEWS b/NEWS index fcfab44..f1cedc0 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,7 @@ * Unicode support added to getclip and putclip. * Fix mbstowcs bug in readshortcut causing "buffer overflow detected" from -fstack-protect at runtime. + * Support clipboard use between 32- and 64-bit Cygwin environments. 1.4.15 New maintainer Mark Geisert . diff --git a/src/clip/getclip.c b/src/clip/getclip.c index 82e7070..5cdb8f1 100644 --- a/src/clip/getclip.c +++ b/src/clip/getclip.c @@ -1,5 +1,5 @@ /** - * getclip.exe Copy Windows clipboard to stdout + * getclip.exe Copy Windows clipboard to stdout * * Copyright 2001,2002,2009,2012 by Charles Wilson * All rights reserved. @@ -31,7 +31,8 @@ #include #include #include -#include +#include // for cygcb_t and CYGWIN_NATIVE +#include #define DEBUGGING 0 // Set 1 to display debug output on stderr @@ -40,7 +41,9 @@ typedef struct struct timespec timestamp; size_t len; char data[1]; -} cygcb_t; +} cygcb_old_t; // for cygNewFormat == 1 + +// extern typedef struct cygcb_t is for cygNewFormat == 2 typedef struct { @@ -63,10 +66,10 @@ static const char copyrightID[] = typedef struct { - int endl_mode; /* ENDLMODE_DOS ENDLMODE_UNIX ENDLMODE_NOCONV */ - int unixflag; /* indicates that the user specified -u or --unix */ - int dosflag; /* indicates that the user specified -d or --dos */ - int noconvflag; /* indicates that the user specified -n or --no-conv */ + int endl_mode; /* ENDLMODE_DOS ENDLMODE_UNIX ENDLMODE_NOCONV */ + int unixflag; /* indicates that the user specified -u or --unix */ + int dosflag; /* indicates that the user specified -d or --dos */ + int noconvflag; /* indicates that the user specified -n or --no-conv */ } flags_struct; static void printTopDescription (FILE * f, char *name); @@ -198,6 +201,8 @@ main (int argc, const char **argv) goto exit; } rest = poptGetArgs (optCon); + + setlocale (LC_ALL, ""); if (rest == NULL) ec |= getclip (stdout, flags, stderr, program_name); else @@ -308,9 +313,9 @@ static void getCygVer(cygwin_version_data* verInfo) break; if (strncasecmp (buf, "dll major:", 10) == 0) { - char c = '\0'; - /* assumes 'p-(buf+11)' <= 7 */ - memcpy (dll_major, buf + 11, p - (buf + 11)); + char c = '\0'; + /* assumes 'p-(buf+11)' <= 7 */ + memcpy (dll_major, buf + 11, p - (buf + 11)); c = dll_major[1]; dll_major[1] = '\0'; verInfo->dll_major = atoi (dll_major); @@ -321,18 +326,18 @@ static void getCygVer(cygwin_version_data* verInfo) if (strncasecmp (buf, "dll minor:", 10) == 0) { verInfo->dll_micro = atoi (buf + 11); - continue; - } + continue; + } if (strncasecmp (buf, "api major:", 10) == 0) - { + { verInfo->api_major = atoi (buf + 11); - continue; - } + continue; + } if (strncasecmp (buf, "api minor:", 10) == 0) - { + { verInfo->api_minor = atoi (buf + 11); - continue; - } + continue; + } } } @@ -344,21 +349,25 @@ getclip (FILE * out, flags_struct flags, FILE * f, char *name) size_t len = 0; char *newStr = NULL; int origMode; - int cygNewFormat = 0; + int cygNewFormat; + int cygversion; cygwin_version_data verInfo; getCygVer(&verInfo); - if ((verInfo.dll_major > 1) || - ((verInfo.dll_major == 1) && (verInfo.dll_minor > 7)) || - ((verInfo.dll_major == 1) && (verInfo.dll_minor == 7) && - (verInfo.dll_micro >= 13))) + cygversion = verInfo.dll_micro; + cygversion += verInfo.dll_minor * 100; + cygversion += verInfo.dll_major * 100 * 100; + if (cygversion < 10713) + cygNewFormat = 0; + else if (cygversion < 30300) cygNewFormat = 1; + else + cygNewFormat = 2; origMode = setmode (fileno (out), O_BINARY); if (flags.endl_mode == ENDLMODE_NOCONV) { - const char *CYGWIN_NATIVE = "CYGWIN_NATIVE_CLIPBOARD"; UINT cygnativeformat; UINT formatlist[3]; UINT format; @@ -378,7 +387,7 @@ getclip (FILE * out, flags_struct flags, FILE * f, char *name) fprintf (stderr, "\n"); } #endif - cygnativeformat = RegisterClipboardFormat (CYGWIN_NATIVE); + cygnativeformat = RegisterClipboardFormatW (CYGWIN_NATIVE); formatlist[0] = cygnativeformat; formatlist[1] = CF_UNICODETEXT; @@ -394,17 +403,21 @@ getclip (FILE * out, flags_struct flags, FILE * f, char *name) if (format == cygnativeformat) { - if (cygNewFormat) - { + if (cygNewFormat) + { cygcb_t *clipbuf = (cygcb_t *) GlobalLock (hglb); + cygcb_old_t *clipold = (cygcb_old_t *) clipbuf; if (clipbuf) { - fwrite (clipbuf->data, sizeof (char), clipbuf->len, out); + if (cygNewFormat == 2) + fwrite (&clipbuf[1], sizeof (char), clipbuf->cb_size, out); + else + fwrite (clipold->data, sizeof (char), clipold->len, out); GlobalUnlock (hglb); } - } - else - { + } + else + { char *nativebuf = (char *) GlobalLock (hglb); if (nativebuf) { @@ -415,7 +428,7 @@ getclip (FILE * out, flags_struct flags, FILE * f, char *name) fwrite (buf, sizeof (char), len, out); GlobalUnlock (hglb); } - } + } } else if (format == CF_UNICODETEXT) { @@ -423,18 +436,15 @@ getclip (FILE * out, flags_struct flags, FILE * f, char *name) if (lpwstr) { int srclen = wcslen (lpwstr); // wide-char count - int dstlen = srclen << 2; // byte count + int dstlen = srclen << 2; // heuristic for byte count LPSTR dst = (LPSTR) malloc (dstlen); - int res = WideCharToMultiByte (CP_UTF8, 0, lpwstr, srclen, - dst, dstlen, NULL, NULL); + int res = wcstombs (dst, lpwstr, dstlen); if (res > 0) fwrite (dst, sizeof (char), res, out); - else if (res == 0) + else if (res == -1) { #if DEBUGGING - DWORD err = GetLastError (); - /* look up error code displayed here in w32api/winerror.h */ - fprintf (stderr, "WideCharToMultiByte returns %ld\n", err); + fprintf (stderr, "wcstombs: %s\n", strerror (errno)); #endif } free (dst); diff --git a/src/clip/putclip.c b/src/clip/putclip.c index 76bddeb..13158bd 100644 --- a/src/clip/putclip.c +++ b/src/clip/putclip.c @@ -31,7 +31,8 @@ #include #include #include -#include +#include // for cygcb_t and CYGWIN_NATIVE +#include #define DEBUGGING 0 // Set 1 to display debug output on stderr @@ -40,7 +41,9 @@ typedef struct struct timespec timestamp; size_t len; char data[1]; -} cygcb_t; +} cygcb_old_t; // for cygNewFormat == 1 + +// extern typedef struct cygcb_t is for cygNewFormat == 2 typedef struct { @@ -69,10 +72,10 @@ static const char copyrightID[] = typedef struct { - int endl_mode; /* ENDLMODE_DOS ENDLMODE_UNIX ENDLMODE_NOCONV */ - int unixflag; /* indicates that the user specified -u or --unix */ - int dosflag; /* indicates that the user specified -d or --dos */ - int noconvflag; /* indicates that the user specified -n or --no-conv */ + int endl_mode; /* ENDLMODE_DOS ENDLMODE_UNIX ENDLMODE_NOCONV */ + int unixflag; /* indicates that the user specified -u or --unix */ + int dosflag; /* indicates that the user specified -d or --dos */ + int noconvflag; /* indicates that the user specified -n or --no-conv */ } flags_struct; static void printTopDescription (FILE * f, char *name); @@ -198,6 +201,7 @@ main (int argc, const char **argv) rest = poptGetArgs (optCon); + setlocale (LC_ALL, ""); if (rest == NULL) ec |= putclip (stdin, flags, stderr, program_name); else @@ -348,19 +352,24 @@ putclip (FILE * in, flags_struct flags, FILE * f, char *name) int len = 0; int convlen = 0; int numread; - int cygNewFormat = 0; + int cygNewFormat; + int cygversion; cygwin_version_data verInfo; getCygVer(&verInfo); - if ((verInfo.dll_major > 1) || - ((verInfo.dll_major == 1) && (verInfo.dll_minor > 7)) || - ((verInfo.dll_major == 1) && (verInfo.dll_minor == 7) && - (verInfo.dll_micro >= 13))) + cygversion = verInfo.dll_micro; + cygversion += verInfo.dll_minor * 100; + cygversion += verInfo.dll_major * 100 * 100; + if (cygversion < 10713) + cygNewFormat = 0; + else if (cygversion < 30300) cygNewFormat = 1; + else + cygNewFormat = 2; /* Since we have to copy to the clipboard all in one step, - read entire stream into memory. However, let's try to - do this using the minimum amount of memory, but keep + read entire stream into memory. However, let's try to + do this using the minimum amount of memory, but keep allocating more if needed. */ do @@ -398,23 +407,9 @@ putclip (FILE * in, flags_struct flags, FILE * f, char *name) /* format the string according to flags */ if (buf) { - const char *CYGWIN_NATIVE = "CYGWIN_NATIVE_CLIPBOARD"; UINT cygnativeformat; - if (!OpenClipboard (0)) - { - fprintf (stderr, "Unable to open the clipboard\n"); -#if DEBUGGING - DWORD err = GetLastError (); - /* look up error code displayed here in w32api/winerror.h */ - fprintf (stderr, "OpenClipboard returns %ld\n", err); -#endif - return (PUTCLIP_ERR); - } - cygnativeformat = RegisterClipboardFormat (CYGWIN_NATIVE); - CloseClipboard (); - - // if flags.endl_mode == ENDLMODE_NOCONV + // if flags.endl_mode == ENDLMODE_NOCONV convbuf = buf; convlen = len; @@ -537,32 +532,44 @@ putclip (FILE * in, flags_struct flags, FILE * f, char *name) /* look up error code displayed here in w32api/winerror.h */ fprintf (stderr, "OpenClipboard returns %ld\n", err); #endif - if (convbuf) - free (convbuf); - return (PUTCLIP_ERR); + goto failout2; + } + cygnativeformat = RegisterClipboardFormatW (CYGWIN_NATIVE); + + switch (cygNewFormat) + { + case 2: + hData = GlobalAlloc (GMEM_MOVEABLE, convlen + sizeof (cygcb_t)); + break; + case 1: + hData = GlobalAlloc (GMEM_MOVEABLE, convlen + sizeof (cygcb_old_t)); + break; + case 0: + hData = GlobalAlloc (GMEM_MOVEABLE, convlen + sizeof (size_t)); + break; } - if (cygNewFormat) - hData = GlobalAlloc (GMEM_MOVEABLE, convlen + sizeof (cygcb_t)); - else - hData = GlobalAlloc (GMEM_MOVEABLE, convlen + sizeof (size_t)); if (!hData) { fprintf (f, "Couldn't allocate global buffer for write.\n"); - if (convbuf) - free (convbuf); - return (PUTCLIP_ERR); + goto failout; } if (!(clipbuf = (void *) GlobalLock (hData))) { fprintf (f, "Couldn't lock global buffer.\n"); - free (convbuf); - return (PUTCLIP_ERR); + goto failout; } - if (cygNewFormat) + if (cygNewFormat == 2) { cygcb_t *clipbufX = (cygcb_t *) clipbuf; + clipbufX->cb_size = convlen; + clock_gettime (CLOCK_REALTIME, &clipbufX->ts); + memcpy (&clipbufX[1], convbuf, convlen); + } + else if (cygNewFormat == 1) + { + cygcb_old_t *clipbufX = (cygcb_old_t *) clipbuf; clipbufX->len = convlen; clock_gettime (CLOCK_REALTIME, &clipbufX->timestamp); memcpy (clipbufX->data, convbuf, convlen); @@ -577,65 +584,47 @@ putclip (FILE * in, flags_struct flags, FILE * f, char *name) if (!SetClipboardData (cygnativeformat, hData)) { fprintf (f, - "Couldn't write native format to the clipboard %04x %x\n", + "Couldn't write native format to the clipboard %04x %p\n", cygnativeformat, hData); #if DEBUGGING DWORD err = GetLastError (); /* look up error code displayed here in w32api/winerror.h */ fprintf (stderr, "SetClipboardData returns %ld\n", err); #endif - free (convbuf); - return (PUTCLIP_ERR); + goto failout; } - CloseClipboard (); -#if 0 // Per MSDN, don't GlobalFree a handle successfully transferred to system - if (GlobalFree (hData)) - { - fprintf (f, - "Couldn't free global buffer after write to clipboard.\n"); - free (convbuf); - return (PUTCLIP_ERR); - } -#endif +/* Per MSDN, don't GlobalFree a handle successfully transferred to system + * if (GlobalFree (hData)) + * { + * fprintf (f, + * "Couldn't free global buffer after write to clipboard.\n"); + * goto failout; + * } + */ hData = NULL; clipbuf = NULL; /* CF_UNICODETEXT format */ - if (!OpenClipboard (0)) - { - fprintf (f, "Unable to open the clipboard\n"); -#if DEBUGGING - DWORD err = GetLastError (); - /* look up error code displayed here in w32api/winerror.h */ - fprintf (stderr, "OpenClipboard returns %ld\n", err); -#endif - free (convbuf); - return (PUTCLIP_ERR); - } if (!(hData = GlobalAlloc (GMEM_MOVEABLE, sizeof (WCHAR) * convlen + 2))) { fprintf (f, "Couldn't allocate global buffer for write.\n"); - free (convbuf); - return (PUTCLIP_ERR); + goto failout; } if (!(clipbuf = (void *) GlobalLock (hData))) { fprintf (f, "Couldn't lock global buffer.\n"); - free (convbuf); - return (PUTCLIP_ERR); + goto failout; } - int res = MultiByteToWideChar (CP_UTF8, 0, convbuf, convlen, - (LPWSTR) clipbuf, convlen + 1); - if (res == 0) + convbuf[convlen] = '\0'; + int res = mbstowcs (clipbuf, convbuf, convlen + 1); + if (res == -1) { #if DEBUGGING - DWORD err = GetLastError (); - /* look up error code displayed here in w32api/winerror.h */ - fprintf (stderr, "MultiByteToWideChar returns %ld\n", err); + fprintf (stderr, "mbstowcs: %s\n", strerror (errno)); #endif } - else /* res != 0 */ + else /* res != -1 */ { *((WCHAR *) clipbuf + res) = 0; /* NULL-terminate just in case */ #if DEBUGGING @@ -652,45 +641,29 @@ putclip (FILE * in, flags_struct flags, FILE * f, char *name) /* look up error code displayed here in w32api/winerror.h */ fprintf (stderr, "SetClipboardData returns %ld\n", err); #endif - free (convbuf); - return (PUTCLIP_ERR); + goto failout; } - CloseClipboard (); -#if 0 // Per MSDN, don't GlobalFree a handle successfully transferred to system - if (GlobalFree (hData)) - { - fprintf (f, - "Couldn't free global buffer after write to clipboard.\n"); - free (convbuf); - return (PUTCLIP_ERR); - } -#endif +/* Per MSDN, don't GlobalFree a handle successfully transferred to system + * if (GlobalFree (hData)) + * { + * fprintf (f, + * "Couldn't free global buffer after write to clipboard.\n"); + * goto failout; + * } + */ hData = NULL; clipbuf = NULL; /* CF_TEXT format */ - if (!OpenClipboard (0)) - { - fprintf (f, "Unable to open the clipboard\n"); -#if DEBUGGING - DWORD err = GetLastError (); - /* look up error code displayed here in w32api/winerror.h */ - fprintf (stderr, "OpenClipboard returns %ld\n", err); -#endif - free (convbuf); - return (PUTCLIP_ERR); - } if (!(hData = GlobalAlloc (GMEM_MOVEABLE, convlen + 2))) { fprintf (f, "Couldn't allocate global buffer for write.\n"); - free (convbuf); - return (PUTCLIP_ERR); + goto failout; } if (!(clipbuf = (void *) GlobalLock (hData))) { fprintf (f, "Couldn't lock global buffer.\n"); - free (convbuf); - return (PUTCLIP_ERR); + goto failout; } memcpy (clipbuf, convbuf, convlen); @@ -706,19 +679,17 @@ putclip (FILE * in, flags_struct flags, FILE * f, char *name) /* look up error code displayed here in w32api/winerror.h */ fprintf (stderr, "SetClipboardData returns %ld\n", err); #endif - free (convbuf); - return (PUTCLIP_ERR); + goto failout; } CloseClipboard (); -#if 0 // Per MSDN, don't GlobalFree a handle successfully transferred to system - if (GlobalFree (hData)) - { - fprintf (f, - "Couldn't free global buffer after write to clipboard.\n"); - free (convbuf); - return (PUTCLIP_ERR); - } -#endif +/* Per MSDN, don't GlobalFree a handle successfully transferred to system + * if (GlobalFree (hData)) + * { + * fprintf (f, + * "Couldn't free global buffer after write to clipboard.\n"); + * goto failout; + * } + */ hData = NULL; clipbuf = NULL; @@ -731,4 +702,11 @@ putclip (FILE * in, flags_struct flags, FILE * f, char *name) CloseClipboard (); } return (PUTCLIP_OK); + +failout: + CloseClipboard (); +failout2: + if (convbuf) + free (convbuf); + return (PUTCLIP_ERR); }