修訂 | c4788dd4bc3fc29d1beda2cec07c089d0e935947 (tree) |
---|---|
時間 | 2018-07-13 13:44:06 |
作者 | Agustina Arzille <avarzille@rise...> |
Commiter | Agustina Arzille |
Fix argument check in functions with kwargs
@@ -73,9 +73,10 @@ | ||
73 | 73 | public: |
74 | 74 | enum |
75 | 75 | { |
76 | - flg_outer_ref = 0x01, | |
77 | - flg_captured = 0x02, | |
78 | - flg_toplevel = 0x04 | |
76 | + flg_outer_ref = 0x01, | |
77 | + flg_captured = 0x02, | |
78 | + flg_toplevel = 0x04, | |
79 | + flg_kwargs = 0x08 | |
79 | 80 | }; |
80 | 81 | |
81 | 82 | class frame_data |
@@ -1777,6 +1778,7 @@ | ||
1777 | 1778 | (void)this->index (make_kwtab (interp, pa.kw, pa.opt.n)); |
1778 | 1779 | this->emit (OPX_(KWARGS), intobj (nreq), intobj (pa.kw.n), |
1779 | 1780 | intobj (atail == NIL ? nargs : -nargs)); |
1781 | + this->rflags |= flg_kwargs; | |
1780 | 1782 | } |
1781 | 1783 | |
1782 | 1784 | cons *first_opt = pa.opt.ptr ? pa.opt.ptr : pa.kw.ptr; |
@@ -1860,7 +1862,9 @@ | ||
1860 | 1862 | else if (r != EVR_IRET) |
1861 | 1863 | this->emit (OPX_(RET)); |
1862 | 1864 | |
1863 | - function *retp = as_fct (alloc_fct (this->interp, flags)); | |
1865 | + function *retp = as_fct (alloc_fct (this->interp, flags | | |
1866 | + ((this->rflags & flg_kwargs) ? function::kwargs_flag : 0))); | |
1867 | + | |
1864 | 1868 | this->interp->push (this->interp->alval); |
1865 | 1869 | retp->bcode = this->encode (); |
1866 | 1870 | retp->vals = this->idxvec (); |
@@ -236,6 +236,7 @@ | ||
236 | 236 | public: |
237 | 237 | local_varobj<T> () |
238 | 238 | { |
239 | + this->full = 0; | |
239 | 240 | this->init_vo (); |
240 | 241 | } |
241 | 242 | }; |
@@ -5,10 +5,14 @@ | ||
5 | 5 | |
6 | 6 | static uint32_t |
7 | 7 | process_keys (interpreter *interp, object kwtab, uint32_t nreq, |
8 | - uint32_t nkw, uint32_t nopt, uint32_t bp, uint32_t nargs) | |
8 | + uint32_t nkw, uint32_t nopt, uint32_t bp, uint32_t nargs, bool va) | |
9 | 9 | { |
10 | 10 | uint32_t extra = nopt + nkw; |
11 | 11 | uint32_t total = nreq + extra; |
12 | + | |
13 | + if (nargs < nreq) | |
14 | + interp->raise_nargs (nreq, total, nargs); | |
15 | + | |
12 | 16 | QP_TMARK (interp); |
13 | 17 | |
14 | 18 | object *argv = (object *)QP_TALLOC (interp, extra * sizeof (*argv)); |
@@ -79,6 +83,16 @@ | ||
79 | 83 | |
80 | 84 | done: |
81 | 85 | uint32_t nrest = nargs - ix; |
86 | + if (qp_unlikely (!va && nrest > 0)) | |
87 | + { | |
88 | + local_varobj<string> ts; | |
89 | + ts.type = typecode::STR; | |
90 | + ts.data = (unsigned char *)fct_sname (interp->caller ()); | |
91 | + ts.nbytes = ustrlen (ts.data, &ts.len); | |
92 | + interp->raise2 ("arg-error", io_sprintf (interp, "apply: excess " | |
93 | + "arguments found after keyword arguments in call to %Q", | |
94 | + ts.as_obj ())); | |
95 | + } | |
82 | 96 | |
83 | 97 | nargs = total + nrest; |
84 | 98 | move_objs (interp->stack + bp + total, |
@@ -776,7 +790,7 @@ | ||
776 | 790 | } |
777 | 791 | |
778 | 792 | nargs = process_keys (interp, *fvals, ix, |
779 | - n, abs (sx) - ix - n, bp, nargs); | |
793 | + n, abs (sx) - ix - n, bp, nargs, sx < 0); | |
780 | 794 | lastf = interp->cur_frame; |
781 | 795 | NEXT_OP; |
782 | 796 |
@@ -846,6 +860,7 @@ | ||
846 | 860 | function *fp = as_fct (alloc_fct (interp)); |
847 | 861 | const auto infct = as_fct (r_stkend (1)); |
848 | 862 | |
863 | + fp->full = infct->full; | |
849 | 864 | fp->max_sp = infct->max_sp; |
850 | 865 | fp->min_argc = infct->min_argc; |
851 | 866 | fp->max_argc = infct->max_argc; |
@@ -44,6 +44,7 @@ | ||
44 | 44 | { |
45 | 45 | public: |
46 | 46 | static const int artificial_flag = 1u << 17; |
47 | + static const int kwargs_flag = 1u << 18; | |
47 | 48 | |
48 | 49 | int max_sp; |
49 | 50 | int min_argc; |
@@ -57,7 +58,8 @@ | ||
57 | 58 | |
58 | 59 | void test_nargs (interpreter *__interp, uint32_t __n) const |
59 | 60 | { |
60 | - if (__n < (uint32_t)this->min_argc || __n > (uint32_t)this->max_argc) | |
61 | + if (!this->flagged_p (kwargs_flag) && | |
62 | + (__n < (uint32_t)this->min_argc || __n > (uint32_t)this->max_argc)) | |
61 | 63 | __interp->raise_nargs (fct_sname (this->as_obj ()), |
62 | 64 | this->min_argc, this->max_argc, __n); |
63 | 65 | } |
@@ -33,9 +33,8 @@ | ||
33 | 33 | object io_sprintf (interpreter *__interp, const char *__fmt, Args... __args) |
34 | 34 | { |
35 | 35 | valref __tmp (__interp, symval (intern (__interp, "%fmt-str", 8))); |
36 | - string __sf; | |
36 | + local_varobj<string> __sf; | |
37 | 37 | |
38 | - __sf.full = 0; | |
39 | 38 | __sf.type = typecode::STR; |
40 | 39 | __sf.data = (unsigned char *)__fmt; |
41 | 40 | __sf.nbytes = ustrlen (__fmt, &__sf.len); |
@@ -34,14 +34,14 @@ | ||
34 | 34 | s + maxlen ? (int)(p - s) : maxlen); |
35 | 35 | } |
36 | 36 | |
37 | -int ustrlen (const char *s, int *lenp) | |
37 | +int ustrlen (const void *xs, int *lenp) | |
38 | 38 | { |
39 | 39 | int i; |
40 | - const char *p; | |
40 | + const uint8_t *s = (const uint8_t *)xs, *p; | |
41 | 41 | |
42 | 42 | for (i = 0, p = s; *p != 0; ++i) |
43 | 43 | { |
44 | - int off = UTF8_SKIP[(uint8_t)*p]; | |
44 | + int off = UTF8_SKIP[*p]; | |
45 | 45 | if (off == 0) |
46 | 46 | return (-1); |
47 | 47 |
@@ -52,14 +52,14 @@ | ||
52 | 52 | return ((int)(p - s)); |
53 | 53 | } |
54 | 54 | |
55 | -int ustrnlen (const char *s, int maxlen) | |
55 | +int ustrnlen (const void *xs, int maxlen) | |
56 | 56 | { |
57 | 57 | int i; |
58 | - const char *end = s + maxlen; | |
58 | + const uint8_t *s = (const uint8_t *)xs, *end = s + maxlen; | |
59 | 59 | |
60 | 60 | for (i = 0; s < end; ++i) |
61 | 61 | { |
62 | - int off = UTF8_SKIP[(uint8_t)*s]; | |
62 | + int off = UTF8_SKIP[*s]; | |
63 | 63 | if (off == 0) |
64 | 64 | return (-1); |
65 | 65 |
@@ -138,9 +138,9 @@ | ||
138 | 138 | |
139 | 139 | QP_EXPORT int utf8min (const char *__s, int __n); |
140 | 140 | |
141 | -QP_EXPORT int ustrlen (const char *__s, int *__lenp); | |
141 | +QP_EXPORT int ustrlen (const void *__s, int *__lenp); | |
142 | 142 | |
143 | -QP_EXPORT int ustrnlen (const char *__s, int __bytes); | |
143 | +QP_EXPORT int ustrnlen (const void *__s, int __bytes); | |
144 | 144 | |
145 | 145 | QP_EXPORT int ustroff (const unsigned char *__p, int __idx); |
146 | 146 |