Browse Source

Merge pull request #4610 from mandel59/java_hashcode

Fix issue #4608
Cauê Waneck 9 years ago
parent
commit
582f8843b2
3 changed files with 36 additions and 4 deletions
  1. 20 3
      genjava.ml
  2. 1 1
      genpy.ml
  3. 15 0
      tests/unit/src/unit/issues/Issue4608.hx

+ 20 - 3
genjava.ml

@@ -296,11 +296,28 @@ struct
 	let priority = solve_deps name [ DAfter ExpressionUnwrap.priority; DAfter ObjectDeclMap.priority; DAfter ArrayDeclSynf.priority; DBefore IntDivisionSynf.priority ]
 	let priority = solve_deps name [ DAfter ExpressionUnwrap.priority; DAfter ObjectDeclMap.priority; DAfter ArrayDeclSynf.priority; DBefore IntDivisionSynf.priority ]
 
 
 	let java_hash s =
 	let java_hash s =
+		let high_surrogate c = (c lsr 10) + 0xD7C0 in
+		let low_surrogate c = (c land 0x3FF) lor 0xDC00 in
 		let h = ref Int32.zero in
 		let h = ref Int32.zero in
 		let thirtyone = Int32.of_int 31 in
 		let thirtyone = Int32.of_int 31 in
-		for i = 0 to String.length s - 1 do
-			h := Int32.add (Int32.mul thirtyone !h) (Int32.of_int (int_of_char (String.unsafe_get s i)));
-		done;
+		(try
+			UTF8.validate s;
+			UTF8.iter (fun c ->
+				let c = (UChar.code c) in
+				if c > 0xFFFF then
+					(h := Int32.add (Int32.mul thirtyone !h)
+						(Int32.of_int (high_surrogate c));
+					h := Int32.add (Int32.mul thirtyone !h)
+						(Int32.of_int (low_surrogate c)))
+				else
+					h := Int32.add (Int32.mul thirtyone !h)
+						(Int32.of_int c)
+				) s
+		with UTF8.Malformed_code ->
+			String.iter (fun c ->
+				h := Int32.add (Int32.mul thirtyone !h)
+					(Int32.of_int (Char.code c))) s
+		);
 		!h
 		!h
 
 
 	let rec is_final_return_expr is_switch e =
 	let rec is_final_return_expr is_switch e =

+ 1 - 1
genpy.ml

@@ -403,7 +403,7 @@ module Transformer = struct
 			List.iter (fun es ->
 			List.iter (fun es ->
 				match es.eexpr with
 				match es.eexpr with
 				| TConst (TString s) ->
 				| TConst (TString s) ->
-					let l = String.length s in
+					let l = UTF8.length s in
 					let sl = try
 					let sl = try
 						Hashtbl.find length_map l
 						Hashtbl.find length_map l
 					with Not_found ->
 					with Not_found ->

+ 15 - 0
tests/unit/src/unit/issues/Issue4608.hx

@@ -0,0 +1,15 @@
+package unit.issues;
+
+class Issue4608 extends Test {
+    function test() {
+        var s = "𩸽あëa";
+        var b = false;
+        switch s {
+        case "𩸽あëa":
+            b = true;
+        case "a":
+        case _:
+        }
+        t(b);
+    }
+}