Browse Source

PuTTY snapshot a101444d (New script to draw the icons as SVG – 2022-03-18 – current)

Source commit: 8c85471f1d873833dd2e36c97a111c0f297df200
Martin Prikryl 3 năm trước cách đây
mục cha
commit
095f5140af

+ 4 - 0
source/putty/defs.h

@@ -42,6 +42,8 @@
 #define SIZEx "Ix"
 #define SIZEu "Iu"
 uintmax_t strtoumax(const char *nptr, char **endptr, int base);
+/* Also, define a LEGACY_WINDOWS flag to enable other workarounds */
+#define LEGACY_WINDOWS
 #else
 #include <inttypes.h>
 /* Because we still support older MSVC libraries which don't recognise the
@@ -192,6 +194,8 @@ typedef struct logblank_t logblank_t;
 typedef struct BinaryPacketProtocol BinaryPacketProtocol;
 typedef struct PacketProtocolLayer PacketProtocolLayer;
 
+struct unicode_data;
+
 /* Do a compile-time type-check of 'to_check' (without evaluating it),
  * as a side effect of returning the value 'to_return'. Note that
  * although this macro double-*expands* to_return, it always

+ 1 - 1
source/putty/doc/puttydoc.txt

@@ -11448,5 +11448,5 @@ Appendix G: SSH-2 names specified for PuTTY
                user will have to supply a passphrase before the key can be
                used).
 
-       ersionid PuTTY development snapshot 2022-02-23.d73a6d6
+       ersionid PuTTY development snapshot 2022-03-28.a101444
 

+ 1 - 1
source/putty/doc/version.but

@@ -1 +1 @@
-ersionid PuTTY development snapshot 2022-02-23.d73a6d6
+ersionid PuTTY development snapshot 2022-03-28.a101444

+ 15 - 0
source/putty/misc.h

@@ -67,6 +67,10 @@ void strbuf_finalise_agent_query(strbuf *buf);
  * work around the rather deficient interface of mb_to_wc. */
 wchar_t *dup_mb_to_wc_c(int codepage, int flags, const char *string, int len);
 wchar_t *dup_mb_to_wc(int codepage, int flags, const char *string);
+char *dup_wc_to_mb_c(int codepage, int flags, const wchar_t *string, int len,
+                     const char *defchr, struct unicode_data *ucsdata);
+char *dup_wc_to_mb(int codepage, int flags, const wchar_t *string,
+                   const char *defchr, struct unicode_data *ucsdata);
 
 static inline int toint(unsigned u)
 {
@@ -217,6 +221,17 @@ size_t encode_utf8(void *output, unsigned long ch);
  * encoded in UTF-16. */
 char *encode_wide_string_as_utf8(const wchar_t *wstr);
 
+/* Decode a single UTF-8 character. Returns U+FFFD for any of the
+ * illegal cases. */
+unsigned long decode_utf8(const char **utf8);
+
+/* Decode a single UTF-8 character to an output buffer of the
+ * platform's wchar_t. May write a pair of surrogates if
+ * sizeof(wchar_t) == 2, assuming that in that case the wide string is
+ * encoded in UTF-16. Otherwise, writes one character. Returns the
+ * number written. */
+size_t decode_utf8_to_wchar(const char **utf8, wchar_t *out);
+
 /* Write a string out in C string-literal format. */
 void write_c_string_literal(FILE *fp, ptrlen str);
 

+ 11 - 9
source/putty/proxy/interactor.c

@@ -47,8 +47,18 @@ void interactor_return_seat(Interactor *itr)
     if (!is_tempseat(tempseat))
         return;                        /* no-op */
 
-    tempseat_flush(tempseat);
+    /*
+     * We're about to hand this seat back to the parent Interactor to
+     * do its own thing with. It will typically expect to start in the
+     * same state as if the seat had never been borrowed, i.e. in the
+     * starting trust state.
+     *
+     * However, this may be overridden by the tempseat_flush call.
+     */
     Seat *realseat = tempseat_get_real(tempseat);
+    seat_set_trust_status(realseat, true);
+
+    tempseat_flush(tempseat);
     interactor_set_seat(itr, realseat);
     tempseat_free(tempseat);
 
@@ -60,14 +70,6 @@ void interactor_return_seat(Interactor *itr)
     Interactor *itr_top = interactor_toplevel(itr, NULL);
     if (itr_top->last_to_talk)
         interactor_announce(itr);
-
-    /*
-     * We're about to hand this seat back to the parent Interactor to
-     * do its own thing with. It will typically expect to start in the
-     * same state as if the seat had never been borrowed, i.e. in the
-     * starting trust state.
-     */
-    seat_set_trust_status(realseat, true);
 }
 
 InteractionReadySeat interactor_announce(Interactor *itr)

+ 4 - 4
source/putty/version.h

@@ -1,5 +1,5 @@
 /* Generated by automated build script */
-#define PRERELEASE 0.77
-#define TEXTVER "Pre-release 0.77:2022-01-23.f11b201"
-#define SSHVER "-Prerelease-0.77:20220123.f11b201"
-#define BINARY_VERSION 0,76,33965,0
+#define SNAPSHOT
+#define TEXTVER "Development snapshot 2022-03-28.a101444"
+#define SSHVER "-Snapshot-2022-03-28.a101444"
+#define BINARY_VERSION 0,76,1261,0

+ 1 - 1
source/putty/windows/platform.h

@@ -576,6 +576,7 @@ void dll_hijacking_protection(void);
 const char *get_system_dir(void);
 HMODULE load_system32_dll(const char *libname);
 const char *win_strerror(int error);
+bool should_have_security(void);
 void restrict_process_acl(void);
 bool restricted_acl(void);
 void escape_registry_key(const char *in, strbuf *out);
@@ -608,7 +609,6 @@ void EnableSizeTip(bool bEnable);
 /*
  * Exports from unicode.c.
  */
-struct unicode_data;
 void init_ucs(Conf *, struct unicode_data *);
 
 /*

+ 81 - 4
source/putty/windows/unicode.c

@@ -1195,16 +1195,93 @@ int wc_to_mb(int codepage, int flags, const wchar_t *wcstr, int wclen,
         }
         return p - mbstr;
     } else {
-        int defused;
-        return WideCharToMultiByte(codepage, flags, wcstr, wclen,
-                                   mbstr, mblen, defchr, &defused);
+        int defused, ret;
+        ret = WideCharToMultiByte(codepage, flags, wcstr, wclen,
+                                  mbstr, mblen, defchr, &defused);
+        if (ret)
+            return ret;
+
+#ifdef LEGACY_WINDOWS
+        /*
+         * Fallback for legacy platforms too old to support UTF-8: if
+         * the codepage is UTF-8, we can do the translation ourselves.
+         */
+        if (codepage == CP_UTF8 && mblen > 0 && wclen > 0) {
+            size_t remaining = mblen;
+            char *p = mbstr;
+
+            while (wclen > 0) {
+                unsigned long wc = (wclen--, *wcstr++);
+                if (wclen > 0 && IS_SURROGATE_PAIR(wc, *wcstr)) {
+                    wc = FROM_SURROGATES(wc, *wcstr);
+                    wclen--, wcstr++;
+                }
+
+                char utfbuf[6];
+                size_t utflen = encode_utf8(utfbuf, wc);
+                if (utflen <= remaining) {
+                    memcpy(p, utfbuf, utflen);
+                    p += utflen;
+                    remaining -= utflen;
+                } else {
+                    return p - mbstr;
+                }
+            }
+
+            return p - mbstr;
+        }
+#endif
+
+        /* No other fallbacks are available */
+        return 0;
     }
 }
 
 int mb_to_wc(int codepage, int flags, const char *mbstr, int mblen,
              wchar_t *wcstr, int wclen)
 {
-    return MultiByteToWideChar(codepage, flags, mbstr, mblen, wcstr, wclen);
+    int ret = MultiByteToWideChar(codepage, flags, mbstr, mblen, wcstr, wclen);
+    if (ret)
+        return ret;
+
+#ifdef LEGACY_WINDOWS
+    /*
+     * Fallback for legacy platforms too old to support UTF-8: if the
+     * codepage is UTF-8, we can do the translation ourselves.
+     */
+    if (codepage == CP_UTF8 && mblen > 0 && wclen > 0) {
+        size_t remaining = wclen;
+        wchar_t *p = wcstr;
+
+        while (mblen > 0) {
+            char utfbuf[7];
+            int thissize = mblen < 6 ? mblen : 6;
+            memcpy(utfbuf, mbstr, thissize);
+            utfbuf[thissize] = '\0';
+
+            const char *utfptr = utfbuf;
+            wchar_t wcbuf[2];
+            size_t nwc = decode_utf8_to_wchar(&utfptr, wcbuf);
+
+            for (size_t i = 0; i < nwc; i++) {
+                if (remaining > 0) {
+                    remaining--;
+                    *p++ = wcbuf[i];
+                } else {
+                    return p - wcstr;
+                }
+            }
+
+            mbstr += (utfptr - utfbuf);
+            mblen -= (utfptr - utfbuf);
+        }
+
+        return p - wcstr;
+    }
+#endif
+
+    /* No other fallbacks are available */
+    return 0;
 }
 
 bool is_dbcs_leadbyte(int codepage, char byte)

+ 52 - 14
source/putty/windows/utils/open_for_write_would_lose_data.c

@@ -4,20 +4,19 @@
 
 #include "putty.h"
 
-bool open_for_write_would_lose_data(const Filename *fn)
+/*
+ * This is slightly fiddly because we want to be backwards-compatible
+ * with systems too old to have GetFileAttributesEx. The next best
+ * thing is FindFirstFile, which will return a different data
+ * structure, but one that also contains the fields we want. (But it
+ * will behave more unhelpfully - for this application - in the
+ * presence of wildcards, so we'd prefer to use GFAE if we can.)
+ */
+
+static inline bool open_for_write_would_lose_data_impl(
+    DWORD dwFileAttributes, DWORD nFileSizeHigh, DWORD nFileSizeLow)
 {
-    WIN32_FILE_ATTRIBUTE_DATA attrs;
-    if (!GetFileAttributesEx(fn->path, GetFileExInfoStandard, &attrs)) {
-        /*
-         * Generally, if we don't identify a specific reason why we
-         * should return true from this function, we return false, and
-         * let the subsequent attempt to open the file for real give a
-         * more useful error message.
-         */
-        return false;
-    }
-    if (attrs.dwFileAttributes & (FILE_ATTRIBUTE_DEVICE |
-                                  FILE_ATTRIBUTE_DIRECTORY)) {
+    if (dwFileAttributes & (FILE_ATTRIBUTE_DEVICE|FILE_ATTRIBUTE_DIRECTORY)) {
         /*
          * File is something other than an ordinary disk file, so
          * opening it for writing will not cause truncation. (It may
@@ -25,7 +24,7 @@ bool open_for_write_would_lose_data(const Filename *fn)
          */
         return false;
     }
-    if (attrs.nFileSizeHigh == 0 && attrs.nFileSizeLow == 0) {
+    if (nFileSizeHigh == 0 && nFileSizeLow == 0) {
         /*
          * File is zero-length (or may be a named pipe, which
          * dwFileAttributes can't tell apart from a regular file), so
@@ -36,3 +35,42 @@ bool open_for_write_would_lose_data(const Filename *fn)
     }
     return true;
 }
+
+bool open_for_write_would_lose_data(const Filename *fn)
+{
+    static HMODULE kernel32_module;
+    DECL_WINDOWS_FUNCTION(static, BOOL, GetFileAttributesExA,
+                          (LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID));
+
+    if (!kernel32_module) {
+        kernel32_module = load_system32_dll("kernel32.dll");
+        GET_WINDOWS_FUNCTION(kernel32_module, GetFileAttributesExA);
+    }
+
+    if (p_GetFileAttributesExA) {
+        WIN32_FILE_ATTRIBUTE_DATA attrs;
+        if (!p_GetFileAttributesExA(fn->path, GetFileExInfoStandard, &attrs)) {
+            /*
+             * Generally, if we don't identify a specific reason why we
+             * should return true from this function, we return false, and
+             * let the subsequent attempt to open the file for real give a
+             * more useful error message.
+             */
+            return false;
+        }
+        return open_for_write_would_lose_data_impl(
+            attrs.dwFileAttributes, attrs.nFileSizeHigh, attrs.nFileSizeLow);
+    } else {
+        WIN32_FIND_DATA fd;
+        HANDLE h = FindFirstFile(fn->path, &fd);
+        if (h == INVALID_HANDLE_VALUE) {
+            /*
+             * As above, if we can't find the file at all, return false.
+             */
+            return false;
+        }
+        CloseHandle(h);
+        return open_for_write_would_lose_data_impl(
+            fd.dwFileAttributes, fd.nFileSizeHigh, fd.nFileSizeLow);
+    }
+}

+ 14 - 0
source/putty/windows/utils/security.c

@@ -20,6 +20,20 @@ DEF_WINDOWS_FUNCTION(GetSecurityInfo);
 DEF_WINDOWS_FUNCTION(SetSecurityInfo);
 DEF_WINDOWS_FUNCTION(SetEntriesInAclA);
 
+bool should_have_security(void)
+{
+#ifdef LEGACY_WINDOWS
+    /* Legacy pre-NT platforms are not expected to have any of these APIs */
+    init_winver();
+    return (osPlatformId == VER_PLATFORM_WIN32_NT);
+#else
+    /* In the up-to-date PuTTY builds which do not support those
+     * platforms, unconditionally return true, to minimise the risk of
+     * compiling out security checks. */
+    return true;
+#endif
+}
+
 bool got_advapi(void)
 {
     static bool attempted = false;