emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/websocket f7d3fb5409 045/114: Fix issue with handling m


From: ELPA Syncer
Subject: [elpa] externals/websocket f7d3fb5409 045/114: Fix issue with handling multibyte characters.
Date: Wed, 15 Feb 2023 20:58:58 -0500 (EST)

branch: externals/websocket
commit f7d3fb5409aed9f5cdb745f0e61a0c43c097588c
Author: Andrew Hyatt <ahyatt@gmail.com>
Commit: Andrew Hyatt <ahyatt@gmail.com>

    Fix issue with handling multibyte characters.
    
    Added new method `websocket-frame-text' to return the payload of a frame
    as utf-8 text.
    
    Added a test to make sure message masked aren't multibyte.
    
    Changed the text in the functional test to multibyte to help test
    against these kinds of issues.
---
 websocket-functional-test.el | 26 +++++++++++++-------------
 websocket-test.el            |  3 +++
 websocket.el                 | 23 +++++++++++++++++------
 3 files changed, 33 insertions(+), 19 deletions(-)

diff --git a/websocket-functional-test.el b/websocket-functional-test.el
index e4470156db..97e21ce4c0 100644
--- a/websocket-functional-test.el
+++ b/websocket-functional-test.el
@@ -52,8 +52,8 @@
   (websocket-open
    "ws://127.0.0.1:9999"
    :on-message (lambda (_websocket frame)
-                 (push (websocket-frame-payload frame) wstest-msgs)
-                 (message "ws frame: %S" (websocket-frame-payload frame))
+                 (push (websocket-frame-text frame) wstest-msgs)
+                 (message "ws frame: %S" (websocket-frame-text frame))
                  (error "Test error (expected)"))
    :on-close (lambda (_websocket) (setq wstest-closed t))))
 
@@ -67,10 +67,10 @@
 
 (assert (null wstest-msgs))
 
-(websocket-send-text wstest-ws "Hi!")
+(websocket-send-text wstest-ws "你好")
 
 (sleep-for 0.1)
-(assert (equal (car wstest-msgs) "You said: Hi!"))
+(assert (equal (car wstest-msgs) "You said: 你好"))
 (setf (websocket-on-error wstest-ws) (lambda (_ws _type _err)))
 (websocket-send-text wstest-ws "Hi after error!")
 (sleep-for 0.1)
@@ -104,8 +104,8 @@
          :on-open (lambda (_websocket)
                     (message "Websocket opened"))
          :on-message (lambda (_websocket frame)
-                       (push (websocket-frame-payload frame) wstest-msgs)
-                       (message "ws frame: %S" (websocket-frame-payload 
frame)))
+                       (push (websocket-frame-text frame) wstest-msgs)
+                       (message "ws frame: %S" (websocket-frame-text frame)))
          :on-close (lambda (_websocket)
                      (message "Websocket closed")
                      (setq wstest-closed t)))
@@ -131,24 +131,24 @@
                     :host 'local
                     :on-message (lambda (ws frame)
                                   (message "Server received text!")
-                                  (websocket-send-text ws
-                                                       
(websocket-frame-payload frame)))
+                                  (websocket-send-text
+                                   ws (websocket-frame-text frame)))
                     :on-open (lambda (_websocket) "Client connection opened!")
                     :on-close (lambda (_websocket)
                                 (setq wstest-closed t)))))
-
   (setq wstest-msgs nil
         wstest-ws
         (websocket-open
          "ws://localhost:9998"
          :on-message (lambda (_websocket frame)
-                       (push (websocket-frame-payload frame) wstest-msgs)
-                       (message "ws frame: %S" (websocket-frame-payload 
frame)))))
+                       (message "ws frame: %S" (websocket-frame-text frame))
+                       (push
+                        (websocket-frame-text frame) wstest-msgs))))
 
   (assert (websocket-openp wstest-ws))
-  (websocket-send-text wstest-ws "Hi to self!")
+  (websocket-send-text wstest-ws "你好")
   (sleep-for 0.3)
-  (assert (equal (car wstest-msgs) "Hi to self!"))
+  (assert (equal (car wstest-msgs) "你好"))
   (websocket-server-close server-conn))
 (assert wstest-closed)
 (websocket-close wstest-ws)
diff --git a/websocket-test.el b/websocket-test.el
index ab6740d209..604eb87919 100644
--- a/websocket-test.el
+++ b/websocket-test.el
@@ -194,6 +194,9 @@
     (should (equal '("ext1" "ext2; a=1")
                    (websocket-negotiated-extensions ws-with-extensions)))))
 
+(ert-deftest websocket-mask-is-unibyte ()
+  (should-not (multibyte-string-p (websocket-mask "\344\275\240\345\245\275" 
"abcdef"))))
+
 (ert-deftest websocket-create-headers ()
   (let ((base-headers (concat "Host: www.example.com\r\n"
                               "Upgrade: websocket\r\n"
diff --git a/websocket.el b/websocket.el
index 8db83c2e6b..03f7d4d133 100644
--- a/websocket.el
+++ b/websocket.el
@@ -4,7 +4,7 @@
 
 ;; Author: Andrew Hyatt <ahyatt@gmail.com>
 ;; Keywords: Communication, Websocket, Server
-;; Version: 1.6
+;; Version: 1.7
 ;;
 ;; This program is free software; you can redistribute it and/or
 ;; modify it under the terms of the GNU General Public License as
@@ -279,14 +279,25 @@ many bytes were consumed from the string."
 
 (defstruct websocket-frame opcode payload length completep)
 
+(defun websocket-frame-text (frame)
+  "Given FRAME, return the payload as a utf-8 encoded string."
+  (assert (websocket-frame-p frame))
+  (decode-coding-string (websocket-frame-payload frame) 'utf-8))
+
 (defun websocket-mask (key data)
   "Using string KEY, mask string DATA according to the RFC.
 This is used to both mask and unmask data."
-  (apply
-   'string
-   (loop for b across data
-         for i from 0 to (length data)
-         collect (logxor (websocket-get-bytes (substring key (mod i 4)) 1) 
b))))
+  ;; If we don't make the string unibyte here, a string of bytes that should be
+  ;; interpreted as a unibyte string will instead be interpreted as a multibyte
+  ;; string of the same length (for example, 6 multibyte chars for 你好 instead
+  ;; of the correct 6 unibyte chars, which would convert into 2 multibyte
+  ;; chars).
+  (string-make-unibyte (apply
+                        'string
+                        (loop for b across data
+                              for i from 0 to (length data)
+                              collect
+                              (logxor (websocket-get-bytes (substring key (mod 
i 4)) 1) b)))))
 
 (defun websocket-ensure-length (s n)
   "Ensure the string S has at most N bytes.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]