History

js: correctness: use integer range checks

There were some cases where a js number (double) was blindly casted to int or uint64, but that can be undefined behavior (out of range to int) or wrong (negative to uint). Now the code throws a js error if the value is out of range. Additionally, commit ec625266 added these checks for the new hooks API, but incorrectly tested int64 range rather than uint64. Fix this too.

Avi Halachmi (:avih) committed 8 years ago

Commit fc567981 parent 6e6ec331 file · +18 −18Browse files

Unified · Split

player/javascript.c+18−18
@@ -76,6 +76,11 @@ static mpv_handle *jclient(js_State *J) · 75 unmodified lines
76 return jctx(J)->client;76 return jctx(J)->client;
77}77}
78 78
79static void pushnode(js_State *J, mpv_node *node);
80static void makenode(void *ta_ctx, mpv_node *dst, js_State *J, int idx);
81static int jsL_checkint(js_State *J, int idx);
82static uint64_t jsL_checkuint64(js_State *J, int idx);
83
79/**********************************************************************84/**********************************************************************
80 * conventions, MuJS notes and vm errors85 * conventions, MuJS notes and vm errors
81 *********************************************************************/86 *********************************************************************/
@@ -372,7 +377,7 @@ static void push_file_content(js_State *J, const char *fname, int limit) · 290 unmodified lines
372// utils.read_file(..). args: fname [,max]. returns [up to max] bytes as string.377// utils.read_file(..). args: fname [,max]. returns [up to max] bytes as string.
373static void script_read_file(js_State *J)378static void script_read_file(js_State *J)
374{379{
375 int limit = js_isundefined(J, 2) ? -1 : js_tonumber(J, 2);380 int limit = js_isundefined(J, 2) ? -1 : jsL_checkint(J, 2);
376 push_file_content(J, js_tostring(J, 1), limit);381 push_file_content(J, js_tostring(J, 1), limit);
377}382}
378 383
@@ -501,11 +506,6 @@ error_out: · 122 unmodified lines
501/**********************************************************************506/**********************************************************************
502 * Main mp.* scripting APIs and helpers507 * Main mp.* scripting APIs and helpers
503 *********************************************************************/508 *********************************************************************/
504static void pushnode(js_State *J, mpv_node *node);
505static void makenode(void *ta_ctx, mpv_node *dst, js_State *J, int idx);
506static int jsL_checkint(js_State *J, int idx);
507static int64_t jsL_checkint64(js_State *J, int idx);
508
509// Return the index in opts of stack[idx] (or of def if undefined), else throws.509// Return the index in opts of stack[idx] (or of def if undefined), else throws.
510static int checkopt(js_State *J, int idx, const char *def, const char *opts[],510static int checkopt(js_State *J, int idx, const char *def, const char *opts[],
511 const char *desc)511 const char *desc)
@@ -686,7 +686,7 @@ static void script__observe_property(js_State *J) · 174 unmodified lines
686 MPV_FORMAT_STRING, MPV_FORMAT_DOUBLE};686 MPV_FORMAT_STRING, MPV_FORMAT_DOUBLE};
687 687
688 mpv_format f = mf[checkopt(J, 3, "none", fmts, "observe type")];688 mpv_format f = mf[checkopt(J, 3, "none", fmts, "observe type")];
689 int e = mpv_observe_property(jclient(J), js_tonumber(J, 1),689 int e = mpv_observe_property(jclient(J), jsL_checkuint64(J, 1),
690 js_tostring(J, 2),690 js_tostring(J, 2),
691 f);691 f);
692 push_status(J, e);692 push_status(J, e);
@@ -695,7 +695,7 @@ static void script__observe_property(js_State *J) · 2 unmodified lines
695// args: id695// args: id
696static void script__unobserve_property(js_State *J)696static void script__unobserve_property(js_State *J)
697{697{
698 int e = mpv_unobserve_property(jclient(J), js_tonumber(J, 1));698 int e = mpv_unobserve_property(jclient(J), jsL_checkuint64(J, 1));
699 push_status(J, e);699 push_status(J, e);
700}700}
701 701
@@ -719,8 +719,8 @@ static void script_get_time_ms(js_State *J) · 17 unmodified lines
719static void script_set_osd_ass(js_State *J)719static void script_set_osd_ass(js_State *J)
720{720{
721 struct script_ctx *ctx = jctx(J);721 struct script_ctx *ctx = jctx(J);
722 int res_x = js_tonumber(J, 1);722 int res_x = jsL_checkint(J, 1);
723 int res_y = js_tonumber(J, 2);723 int res_y = jsL_checkint(J, 2);
724 const char *text = js_tostring(J, 3);724 const char *text = js_tostring(J, 3);
725 osd_set_external(ctx->mpctx->osd, ctx->client, res_x, res_y, (char *)text);725 osd_set_external(ctx->mpctx->osd, ctx->client, res_x, res_y, (char *)text);
726 mp_wakeup_core(ctx->mpctx);726 mp_wakeup_core(ctx->mpctx);
@@ -772,8 +772,8 @@ static void script_input_set_section_mouse_area(js_State *J) · 45 unmodified lines
772{772{
773 char *section = (char *)js_tostring(J, 1);773 char *section = (char *)js_tostring(J, 1);
774 mp_input_set_section_mouse_area(jctx(J)->mpctx->input, section,774 mp_input_set_section_mouse_area(jctx(J)->mpctx->input, section,
775 js_tonumber(J, 2), js_tonumber(J, 3), // x0, y0775 jsL_checkint(J, 2), jsL_checkint(J, 3), // x0, y0
776 js_tonumber(J, 4), js_tonumber(J, 5)); // x1, y1776 jsL_checkint(J, 4), jsL_checkint(J, 5)); // x1, y1
777 push_success(J);777 push_success(J);
778}778}
779 779
@@ -799,14 +799,14 @@ static void script__hook_add(js_State *J) · 19 unmodified lines
799{799{
800 const char *name = js_tostring(J, 1);800 const char *name = js_tostring(J, 1);
801 int pri = jsL_checkint(J, 2);801 int pri = jsL_checkint(J, 2);
802 uint64_t id = jsL_checkint64(J, 3);802 uint64_t id = jsL_checkuint64(J, 3);
803 push_status(J, mpv_hook_add(jclient(J), id, name, pri));803 push_status(J, mpv_hook_add(jclient(J), id, name, pri));
804}804}
805 805
806// args: id (uint)806// args: id (uint)
807static void script__hook_continue(js_State *J)807static void script__hook_continue(js_State *J)
808{808{
809 push_status(J, mpv_hook_continue(jclient(J), jsL_checkint64(J, 1)));809 push_status(J, mpv_hook_continue(jclient(J), jsL_checkuint64(J, 1)));
810}810}
811 811
812/**********************************************************************812/**********************************************************************
@@ -1124,15 +1124,15 @@ static int jsL_checkint(js_State *J, int idx) · 311 unmodified lines
1124{1124{
1125 double d = js_tonumber(J, idx);1125 double d = js_tonumber(J, idx);
1126 if (!(d >= INT_MIN && d <= INT_MAX))1126 if (!(d >= INT_MIN && d <= INT_MAX))
1127 js_error(J, "integer out of range at index %d", idx);1127 js_error(J, "int out of range at index %d", idx);
1128 return d;1128 return d;
1129}1129}
1130 1130
1131static int64_t jsL_checkint64(js_State *J, int idx)1131static uint64_t jsL_checkuint64(js_State *J, int idx)
1132{1132{
1133 double d = js_tonumber(J, idx);1133 double d = js_tonumber(J, idx);
1134 if (!(d >= INT64_MIN && d <= INT64_MAX))1134 if (!(d >= 0 && d <= UINT64_MAX))
1135 js_error(J, "integer out of range at index %d", idx);1135 js_error(J, "uint64 out of range at index %d", idx);
1136 return d;1136 return d;
1137}1137}
1138 1138

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t