@@ -692,7 +692,7 @@ validate_s0(<<C,R/bits>>) when C >= 128 ->
692692validate_s0 (Text ) ->
693693 validate_ascii (Text ).
694694
695- validate_s2 (<<C ,R /bits >>) ->
695+ validate_s2 (<<C ,R /bits >>) when C >= 128 ->
696696 Class = element (C - 127 , utf8_class ()),
697697 case Class of
698698 7 -> validate_s0 (R );
@@ -701,9 +701,11 @@ validate_s2(<<C,R/bits>>) ->
701701 _ -> 1
702702 end ;
703703validate_s2 (<<>>) ->
704- 2 .
704+ 2 ;
705+ validate_s2 (_ ) ->
706+ 1 .
705707
706- validate_s3 (<<C ,R /bits >>) ->
708+ validate_s3 (<<C ,R /bits >>) when C >= 128 ->
707709 Class = element (C - 127 , utf8_class ()),
708710 case Class of
709711 7 -> validate_s2 (R );
@@ -712,38 +714,46 @@ validate_s3(<<C,R/bits>>) ->
712714 _ -> 1
713715 end ;
714716validate_s3 (<<>>) ->
715- 3 .
717+ 3 ;
718+ validate_s3 (_ ) ->
719+ 1 .
716720
717- validate_s4 (<<C ,R /bits >>) ->
721+ validate_s4 (<<C ,R /bits >>) when C >= 128 ->
718722 Class = element (C - 127 , utf8_class ()),
719723 case Class of
720724 7 -> validate_s2 (R );
721725 _ -> 1
722726 end ;
723727validate_s4 (<<>>) ->
724- 4 .
728+ 4 ;
729+ validate_s4 (_ ) ->
730+ 1 .
725731
726- validate_s5 (<<C ,R /bits >>) ->
732+ validate_s5 (<<C ,R /bits >>) when C >= 128 ->
727733 Class = element (C - 127 , utf8_class ()),
728734 case Class of
729735 1 -> validate_s2 (R );
730736 9 -> validate_s2 (R );
731737 _ -> 1
732738 end ;
733739validate_s5 (<<>>) ->
734- 5 .
740+ 5 ;
741+ validate_s5 (_ ) ->
742+ 1 .
735743
736- validate_s6 (<<C ,R /bits >>) ->
744+ validate_s6 (<<C ,R /bits >>) when C >= 128 ->
737745 Class = element (C - 127 , utf8_class ()),
738746 case Class of
739747 7 -> validate_s3 (R );
740748 9 -> validate_s3 (R );
741749 _ -> 1
742750 end ;
743751validate_s6 (<<>>) ->
744- 6 .
752+ 6 ;
753+ validate_s6 (_ ) ->
754+ 1 .
745755
746- validate_s7 (<<C ,R /bits >>) ->
756+ validate_s7 (<<C ,R /bits >>) when C >= 128 ->
747757 Class = element (C - 127 , utf8_class ()),
748758 case Class of
749759 7 -> validate_s3 (R );
@@ -752,16 +762,20 @@ validate_s7(<<C,R/bits>>) ->
752762 _ -> 1
753763 end ;
754764validate_s7 (<<>>) ->
755- 7 .
765+ 7 ;
766+ validate_s7 (_ ) ->
767+ 1 .
756768
757- validate_s8 (<<C ,R /bits >>) ->
769+ validate_s8 (<<C ,R /bits >>) when C >= 128 ->
758770 Class = element (C - 127 , utf8_class ()),
759771 case Class of
760772 1 -> validate_s3 (R );
761773 _ -> 1
762774 end ;
763775validate_s8 (<<>>) ->
764- 8 .
776+ 8 ;
777+ validate_s8 (_ ) ->
778+ 1 .
765779
766780utf8_class () ->
767781 {
@@ -775,6 +789,71 @@ utf8_class() ->
775789 11 ,6 ,6 ,6 ,5 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8
776790 }.
777791
792+ -ifdef (TEST ).
793+
794+ validate_text_valid_test () ->
795+ 0 = validate_text (<<>>, 0 ),
796+ 0 = validate_text (<<" Hello world!" >>, 0 ),
797+ 0 = validate_text (<<16#c2 , 16#a2 >>, 0 ),
798+ 0 = validate_text (<<16#e2 , 16#82 , 16#ac >>, 0 ),
799+ 0 = validate_text (<<16#f0 , 16#9f , 16#98 , 16#80 >>, 0 ),
800+ 2 = validate_text (<<16#c2 >>, 0 ),
801+ 0 = validate_text (<<16#a2 >>, 2 ),
802+ ok .
803+
804+ validate_text_rejects_ascii_after_multibyte_lead_test_ () ->
805+ Tests = [
806+ {<<" s2" >>, <<16#c2 , $A >>},
807+ {<<" s3" >>, <<16#e1 , $A >>},
808+ {<<" s4" >>, <<16#e0 , $A >>},
809+ {<<" s5" >>, <<16#ed , $A >>},
810+ {<<" s6" >>, <<16#f0 , $A >>},
811+ {<<" s7" >>, <<16#f1 , $A >>},
812+ {<<" s8" >>, <<16#f4 , $A >>}
813+ ],
814+ [{Name , fun () -> 1 = validate_text (Text , 0 ) end }
815+ || {Name , Text } <- Tests ].
816+
817+ validate_text_rejects_streamed_ascii_in_continuation_state_test_ () ->
818+ Tests = [
819+ {<<" s2" >>, 2 },
820+ {<<" s3" >>, 3 },
821+ {<<" s4" >>, 4 },
822+ {<<" s5" >>, 5 },
823+ {<<" s6" >>, 6 },
824+ {<<" s7" >>, 7 },
825+ {<<" s8" >>, 8 }
826+ ],
827+ [{Name , fun () -> 1 = validate_text (<<" A" >>, State ) end }
828+ || {Name , State } <- Tests ].
829+
830+ parse_payload_text_utf8_test () ->
831+ Payload = <<16#f0 , 16#9f , 16#98 , 16#80 >>,
832+ {ok , Payload , 0 , <<>>}
833+ = parse_payload (Payload , undefined , 0 , 0 , text , 4 , undefined , #{},
834+ <<0 :3 >>),
835+ ok .
836+
837+ parse_payload_rejects_invalid_utf8_text_test () ->
838+ {error , badencoding }
839+ = parse_payload (<<16#c2 , $A >>, undefined , 0 , 0 , text , 2 ,
840+ undefined , #{}, <<0 :3 >>),
841+ ok .
842+
843+ parse_payload_rejects_invalid_utf8_close_test () ->
844+ {error , badencoding }
845+ = parse_payload (<<1000 :16 , 16#c2 , $A >>, undefined , 0 , 0 ,
846+ close , 4 , undefined , #{}, <<0 :3 >>),
847+ ok .
848+
849+ parse_payload_rejects_streamed_invalid_utf8_fragment_test () ->
850+ {error , badencoding }
851+ = parse_payload (<<" A" >>, undefined , 2 , 0 , fragment , 1 ,
852+ {fin , text , <<0 :3 >>}, #{}, <<0 :3 >>),
853+ ok .
854+
855+ -endif .
856+
778857% % @doc Return a frame tuple from parsed state and data.
779858
780859-spec make_frame (frame_type (), binary (), close_code (), frag_state ()) -> frame ().
0 commit comments