Skip to content

Commit

Permalink
Remove calc requirement, based on observations and suggestions by Jul…
Browse files Browse the repository at this point in the history
…ian Scheid.
  • Loading branch information
ahyatt committed Sep 2, 2012
1 parent 36d675f commit d29b171
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 27 deletions.
9 changes: 5 additions & 4 deletions websocket-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,11 @@
(ert-deftest websocket-get-bytes ()
(should (equal #x5 (websocket-get-bytes "\x5" 1)))
(should (equal #x101 (websocket-get-bytes "\x1\x1" 2)))
(let ((f (lambda () (websocket-get-bytes "\x0\x0\x0\x1\x0\x0\x0\x1" 8))))
(if websocket-test-64-bit-p
(should (equal #x100000001 (funcall f)))
(should-error (funcall f) :type 'websocket-unparseable-frame)))
(should (equal #xffffff
(websocket-get-bytes "\x0\x0\x0\x0\x0\xFF\xFF\xFF" 8)))
(when websocket-test-64-bit-p
(should-error (websocket-get-bytes "\x0\x0\x0\x1\x0\x0\x0\x1" 8)
:type 'websocket-unparseable-frame))
(should-error (websocket-get-bytes "\x0\x0\x0" 3))
(should-error (websocket-get-bytes "\x0" 2) :type 'websocket-unparseable-frame))

Expand Down
44 changes: 21 additions & 23 deletions websocket.el
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@

(require 'bindat)
(require 'url-parse)
(require 'calc)
(eval-when-compile (require 'cl))

;;; Code:
Expand Down Expand Up @@ -197,16 +196,18 @@ This is based on the KEY from the Sec-WebSocket-Key header."
(defun websocket-get-bytes (s n)
"From string S, retrieve the value of N bytes.
Return the value as an unsigned integer. The value N must be a
power of 2, up to 8."
power of 2, up to 8.
We support getting frames up to 4294967295 bytes (2^32) long."
(if (= n 8)
(let* ((32-bit-parts
(bindat-get-field (bindat-unpack '((:val vec 2 u32)) s) :val))
(cval (calc-eval '("(2^32 * $ + $$)") nil
(aref 32-bit-parts 0) (aref 32-bit-parts 1))))
(when (calc-eval '("$ > $$") 'pred cval most-positive-fixnum)
(cval
(logior (lsh (aref 32-bit-parts 0) 32) (aref 32-bit-parts 1))))
(if (= (aref 32-bit-parts 0) 0)
cval
(signal 'websocket-unparseable-frame
"Frame value found too large to parse!"))
(string-to-number cval))
"Frame value found too large to parse!")))
;; n is not 8
(bindat-get-field
(condition-case err
Expand All @@ -226,26 +227,23 @@ power of 2, up to 8."

(defun websocket-to-bytes (val nbytes)
"Encode the integer VAL in NBYTES of data.
NBYTES much be a power of 2, up to 8."
(unless (or (and (< nbytes 8)
(< val (expt 2 (* 8 nbytes))))
(and (= nbytes 8)
(calc-eval "% < 2^(8 * %%)" 'pred val nbytes)))
NBYTES much be a power of 2, up to 8.
This supports encoding values up to "
(when (and (< nbytes 8)
(> val (expt 2 (* 8 nbytes))))
;; not a user-facing error, this must be caused from an error in
;; this library
(error "websocket-to-bytes: Value %d could not be expressed in %d bytes"
val nbytes))
(if (= nbytes 8)
(progn
(when (calc-eval "$ < 4294967296" 'pred most-positive-fixnum)
(signal 'websocket-frame-too-large
most-positive-fixnum))
;; Need to use calc even though at this point things are manageable,
;; since some emacs cannot parse the value 4294967296, even if
;; they never evaluate it.
(bindat-pack `((:val vec 2 u32))
`((:val . [,(calc-eval "floor($ / 4294967296)" 'raw val)
,(calc-eval "$ % 4294967296" 'raw val)]))))
(let ((hi-32bits (lsh val -32))
(low-32bits (logand #xffffffff val)))
(when (> hi-32bits 0)
(signal 'websocket-frame-too-large val))
(bindat-pack `((:val vec 2 u32))
`((:val . [,hi-32bits ,low-32bits])))))
(bindat-pack
`((:val ,(cond ((= nbytes 1) 'u8)
((= nbytes 2) 'u16)
Expand Down Expand Up @@ -507,8 +505,8 @@ also the frame.
The frame may be too large for this buid of emacs, in which case
`websocket-frame-too-large' is returned, with the data of the
system's `most-positive-fixnum', whose length was exceeded. This
also has the `websocket-error' condition."
size of the frame which was too large to process. This also has
the `websocket-error' condition."
(unless (websocket-check frame)
(signal 'websocket-illegal-frame frame))
(websocket-debug websocket "Sending frame, opcode: %s payload: %s"
Expand Down

0 comments on commit d29b171

Please sign in to comment.