Skip to content

Commit 3a45f86

Browse files
author
Hongbo Zhang
committed
more error checking for external names, fix #657, #658
1 parent 69bf4e6 commit 3a45f86

File tree

5 files changed

+71
-12
lines changed

5 files changed

+71
-12
lines changed

jscomp/syntax/ast_external_attributes.ml

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,51 @@ type ffi =
7272

7373
type prim = Primitive.description
7474

75+
let valid_js_char =
76+
let a = Array.init 256 (fun i ->
77+
let c = Char.chr i in
78+
(c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c = '_' || c = '$'
79+
) in
80+
(fun c -> Array.unsafe_get a (Char.code c))
81+
82+
let valid_first_js_char =
83+
let a = Array.init 256 (fun i ->
84+
let c = Char.chr i in
85+
(c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c = '_' || c = '$'
86+
) in
87+
(fun c -> Array.unsafe_get a (Char.code c))
88+
89+
(** Approximation could be improved *)
90+
let valid_ident (s : string) =
91+
let len = String.length s in
92+
valid_js_char s.[0] && valid_first_js_char s.[0] &&
93+
(let module E = struct exception E end in
94+
try
95+
for i = 1 to len - 1 do
96+
if not (valid_js_char (String.unsafe_get s i)) then
97+
raise E.E
98+
done ;
99+
true
100+
with E.E -> false )
101+
102+
let valid_global_name ?loc txt =
103+
let error () =
104+
Location.raise_errorf ?loc "Not a valid name %s" txt in
105+
if txt = "" then
106+
error ()
107+
else
108+
let v = Ext_string.split_by ~keep_empty:true (fun x -> x = '.') txt in
109+
List.iter
110+
(fun s ->
111+
if not (valid_ident s) then error ()
112+
) v
113+
114+
let valid_method_name ?loc txt =
115+
let error () =
116+
Location.raise_errorf ?loc "Not a valid name %s" txt in
117+
if not (valid_ident txt) then error ()
118+
119+
75120
let check_external_module_name ?loc x =
76121
match x with
77122
| {bundle = ""; _ } | {bind_name = Some ""} ->
@@ -85,13 +130,12 @@ let check_external_module_name_opt ?loc x =
85130

86131
let check_ffi ?loc ffi =
87132
match ffi with
88-
| Js_global {txt = ""}
89-
| Js_send {name = ""}
90-
| Js_set ""
91-
| Js_get ""
92-
-> Location.raise_errorf ?loc "empty name encountered"
93-
| Js_global _ | Js_send _ | Js_set _ | Js_get _
94-
| Obj_create _
133+
| Js_global {txt} -> valid_global_name ?loc txt
134+
| Js_send {name }
135+
| Js_set name
136+
| Js_get name
137+
-> valid_method_name ?loc name
138+
| Obj_create _ -> ()
95139
| Js_get_index | Js_set_index
96140
-> ()
97141

@@ -101,10 +145,8 @@ let check_ffi ?loc ffi =
101145
| Js_new {external_module_name ; txt = name}
102146
| Js_call {external_module_name ; txt = {name ; _}}
103147
->
104-
check_external_module_name_opt ?loc external_module_name ;
105-
if name = "" then
106-
Location.raise_errorf ?loc "empty name in externals"
107-
148+
check_external_module_name_opt ?loc external_module_name ;
149+
valid_global_name ?loc name
108150

109151

110152
(**

jscomp/test/.depend

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,8 @@ gpr_459_test.cmj : mt.cmi
269269
gpr_459_test.cmx : mt.cmx
270270
gpr_627_test.cmj : mt.cmi
271271
gpr_627_test.cmx : mt.cmx
272+
gpr_658.cmj : ../runtime/js.cmj
273+
gpr_658.cmx : ../runtime/js.cmx
272274
guide_for_ext.cmj :
273275
guide_for_ext.cmx :
274276
hamming_test.cmj : ../stdlib/printf.cmi mt.cmi ../stdlib/lazy.cmi \
@@ -1041,6 +1043,8 @@ gpr_459_test.cmo : mt.cmi
10411043
gpr_459_test.cmj : mt.cmj
10421044
gpr_627_test.cmo : mt.cmi
10431045
gpr_627_test.cmj : mt.cmj
1046+
gpr_658.cmo : ../runtime/js.cmo
1047+
gpr_658.cmj : ../runtime/js.cmj
10441048
guide_for_ext.cmo :
10451049
guide_for_ext.cmj :
10461050
hamming_test.cmo : ../stdlib/printf.cmi mt.cmi ../stdlib/lazy.cmi \

jscomp/test/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ OTHERS := literals a test_ari test_export2 test_internalOO test_obj_simple_ffi t
6060
bs_rest_test infer_type_test fs_test module_as_function\
6161
test_case_set test_mutliple string_bound_get_test inline_string_test\
6262
ppx_this_obj_test unsafe_obj_external gpr_627_test jsoo_485_test jsoo_400_test \
63-
test_require more_uncurry earger_curry_test poly_type bench mutable_obj_test
63+
test_require more_uncurry earger_curry_test poly_type bench mutable_obj_test gpr_658
6464

6565

6666

jscomp/test/gpr_658.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
'use strict';
2+
3+
4+
5+
/* No side effect */

jscomp/test/gpr_658.ml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
3+
4+
(* external obj : < hi : int > Js.t = "{hi:1}" [@@bs.val] *)
5+
6+
external mk : hi:int -> unit -> < hi : int > Js.t = "" [@@bs.obj]
7+
8+
(* external set_name : < > -> string -> unit = "1name" [@@bs.set] *)

0 commit comments

Comments
 (0)