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 | 3793 | const char *path; |
| 3794 | 3794 | mpv_node *node; |
| 3795 | 3795 | void *ta_parent; |
| 3796 | + int depth; | |
| 3796 | 3797 | }; |
| 3797 | 3798 | |
| 3798 | 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 | 3906 | .arg = act->arg, |
| 3906 | 3907 | }; |
| 3907 | 3908 | |
| 3909 | + if (nctx.depth++ > 100) | |
| 3910 | + return M_PROPERTY_ERROR; | |
| 3908 | 3911 | return do_op_udata(&nctx, M_PROPERTY_KEY_ACTION, &sub_act); |
| 3909 | 3912 | } else { |
| 3910 | 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 | 3922 | struct udata_ctx nctx = *(struct udata_ctx*)ctx; |
| 3920 | 3923 | nctx.node = &nctx.node->u.list->values[item]; |
| 3921 | 3924 | nctx.ta_parent = nctx.node->u.list; |
| 3925 | + nctx.depth = 0; | |
| 3922 | 3926 | |
| 3923 | 3927 | return do_op_udata(&nctx, action, arg); |
| 3924 | 3928 | } |