summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSimon MacMullen <simon@rabbitmq.com>2013-11-04 14:33:33 +0000
committerSimon MacMullen <simon@rabbitmq.com>2013-11-04 14:33:33 +0000
commit2a838a16a6b92acf023234ff79610abc16735694 (patch)
treeae43845b45a0e88381adca45e4d9095d8ac7bfa8 /src
parentdda70faaf01d677d75cdc930b333bc9bb476c7f4 (diff)
downloadrabbitmq-server-git-2a838a16a6b92acf023234ff79610abc16735694.tar.gz
Check UTF-8-ness of shortstrs in non-content-bearing methods. Note that we use the previously developed "fast" checker to avoid a dependency on xmerl, not so much because it is fast.
Diffstat (limited to 'src')
-rw-r--r--src/rabbit_binary_parser.erl44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/rabbit_binary_parser.erl b/src/rabbit_binary_parser.erl
index dc6d090ff0..02835333f1 100644
--- a/src/rabbit_binary_parser.erl
+++ b/src/rabbit_binary_parser.erl
@@ -20,6 +20,7 @@
-export([parse_table/1]).
-export([ensure_content_decoded/1, clear_decoded_content/1]).
+-export([validate_utf8/1, assert_utf8/1]).
%%----------------------------------------------------------------------------
@@ -30,6 +31,8 @@
(rabbit_types:content()) -> rabbit_types:decoded_content()).
-spec(clear_decoded_content/1 ::
(rabbit_types:content()) -> rabbit_types:undecoded_content()).
+-spec(validate_utf8/1 :: (binary()) -> 'ok' | 'error').
+-spec(assert_utf8/1 :: (binary()) -> 'ok').
-endif.
@@ -99,3 +102,44 @@ clear_decoded_content(Content = #content{properties_bin = none}) ->
Content;
clear_decoded_content(Content = #content{}) ->
Content#content{properties = none}.
+
+assert_utf8(B) ->
+ case validate_utf8(B) of
+ ok -> ok;
+ error -> rabbit_misc:protocol_error(
+ frame_error, "Malformed UTF-8 in shortstr", [])
+ end.
+
+validate_utf8(<<C, Cs/binary>>) when C < 16#80 ->
+ %% Plain Ascii character.
+ validate_utf8(Cs);
+validate_utf8(<<C1, C2, Cs/binary>>) when C1 band 16#E0 =:= 16#C0,
+ C2 band 16#C0 =:= 16#80 ->
+ case ((C1 band 16#1F) bsl 6) bor (C2 band 16#3F) of
+ C when 16#80 =< C ->
+ validate_utf8(Cs);
+ _ ->
+ %% Bad range.
+ exit(bad)
+ end;
+validate_utf8(<<C1, C2, C3, Cs/binary>>) when C1 band 16#F0 =:= 16#E0,
+ C2 band 16#C0 =:= 16#80,
+ C3 band 16#C0 =:= 16#80 ->
+ case ((((C1 band 16#0F) bsl 6) bor (C2 band 16#3F)) bsl 6) bor
+ (C3 band 16#3F) of
+ C when 16#800 =< C -> validate_utf8(Cs);
+ _ -> error
+ end;
+validate_utf8(<<C1, C2, C3, C4, Cs/binary>>) when C1 band 16#F8 =:= 16#F0,
+ C2 band 16#C0 =:= 16#80,
+ C3 band 16#C0 =:= 16#80,
+ C4 band 16#C0 =:= 16#80 ->
+ case ((((((C1 band 16#0F) bsl 6) bor (C2 band 16#3F)) bsl 6) bor
+ (C3 band 16#3F)) bsl 6) bor (C4 band 16#3F) of
+ C when 16#10000 =< C -> validate_utf8(Cs);
+ _ -> error
+ end;
+validate_utf8(<<>>) ->
+ ok;
+validate_utf8(_) ->
+ error.