It fixes stack-overflow with keys that contains hundreds of splits. 100 is more than enough for any valid use of user-data, normally key shouldn't contain more than a few splits. Found by OSS-Fuzz.
Unified · Split
| @@ -3793,6 +3793,7 @@ struct udata_ctx { · 3792 unmodified lines | |||
| 3793 | const char *path; | 3793 | const char *path; |
| 3794 | mpv_node *node; | 3794 | mpv_node *node; |
| 3795 | void *ta_parent; | 3795 | void *ta_parent; |
| 3796 | int depth; | ||
| 3796 | }; | 3797 | }; |
| 3797 | 3798 | ||
| 3798 | static int do_op_udata(struct udata_ctx* ctx, int action, void *arg) | 3799 | static int do_op_udata(struct udata_ctx* ctx, int action, void *arg) |
| @@ -3905,6 +3906,8 @@ static int do_op_udata(struct udata_ctx* ctx, int action, void *arg) · 106 unmodified lines | |||
| 3905 | .arg = act->arg, | 3906 | .arg = act->arg, |
| 3906 | }; | 3907 | }; |
| 3907 | 3908 | ||
| 3909 | if (nctx.depth++ > 100) | ||
| 3910 | return M_PROPERTY_ERROR; | ||
| 3908 | return do_op_udata(&nctx, M_PROPERTY_KEY_ACTION, &sub_act); | 3911 | return do_op_udata(&nctx, M_PROPERTY_KEY_ACTION, &sub_act); |
| 3909 | } else { | 3912 | } else { |
| 3910 | return do_op_udata(&nctx, act->action, act->arg); | 3913 | return do_op_udata(&nctx, act->action, act->arg); |
| @@ -3919,6 +3922,7 @@ static int do_list_udata(int item, int action, void *arg, void *ctx) · 8 unmodified lines | |||
| 3919 | struct udata_ctx nctx = *(struct udata_ctx*)ctx; | 3922 | struct udata_ctx nctx = *(struct udata_ctx*)ctx; |
| 3920 | nctx.node = &nctx.node->u.list->values[item]; | 3923 | nctx.node = &nctx.node->u.list->values[item]; |
| 3921 | nctx.ta_parent = nctx.node->u.list; | 3924 | nctx.ta_parent = nctx.node->u.list; |
| 3925 | nctx.depth = 0; | ||
| 3922 | 3926 | ||
| 3923 | return do_op_udata(&nctx, action, arg); | 3927 | return do_op_udata(&nctx, action, arg); |
| 3924 | } | 3928 | } |