diff --git a/lib/websocket/extensions/parser.rb b/lib/websocket/extensions/parser.rb index f8d8891..073dbd0 100644 --- a/lib/websocket/extensions/parser.rb +++ b/lib/websocket/extensions/parser.rb @@ -34,7 +34,7 @@ def self.parse_header(header) if unquoted data = unquoted elsif quoted - data = quoted.gsub(/\\/, '') + data = quoted.gsub(/\\([\x00-\x7f])/, '\1') else data = true end @@ -66,8 +66,8 @@ def self.serialize_params(name, params) when true then values.push(key) when Numeric then values.push(key + '=' + value.to_s) else - if value =~ NOTOKEN - values.push(key + '="' + value.gsub(/"/, '\"') + '"') + if value == '' or value =~ NOTOKEN + values.push(key + '="' + value.gsub(/["\\]/) { |char| '\\' + char } + '"') else values.push(key + '=' + value) end diff --git a/spec/websocket/extensions/parser_spec.rb b/spec/websocket/extensions/parser_spec.rb index 7458210..3f1aa23 100644 --- a/spec/websocket/extensions/parser_spec.rb +++ b/spec/websocket/extensions/parser_spec.rb @@ -55,6 +55,15 @@ def parse(string) ] end + it "round-trips empty and escaped quoted values" do + ["", "a\\b", "a\"b"].each do |value| + header = WebSocket::Extensions::Parser.serialize_params("a", "b" => value) + expect(parse(header)).to eq [ + { :name => "a", :params => { "b" => value } } + ] + end + end + it "parses multiple params" do expect(parse 'a; b; c=1; d="hi"').to eq [ { :name => "a", :params => { "b" => true, "c" => 1, "d" => "hi" } }