diff options
Diffstat (limited to 'bugs')
-rw-r--r-- | bugs | 1015 |
1 files changed, 0 insertions, 1015 deletions
@@ -1,1015 +0,0 @@ | |||
1 | --[=[ | ||
2 | ** lua.stx / llex.c | ||
3 | Tue Dec 2 10:45:48 EDT 1997 | ||
4 | >> BUG: "lastline" was not reset on function entry, so debug information | ||
5 | >> started only in the 2nd line of a function. | ||
6 | |||
7 | |||
8 | |||
9 | ================================================================= | ||
10 | --- Version 3.1 alpha | ||
11 | |||
12 | ** lua.c | ||
13 | Thu Jan 15 14:34:58 EDT 1998 | ||
14 | >> must include "stdlib.h" (for "exit()"). | ||
15 | |||
16 | ** lbuiltin.c / lobject.h | ||
17 | Thu Jan 15 14:34:58 EDT 1998 | ||
18 | >> MAX_WORD may be bigger than MAX_INT | ||
19 | (by lhf) | ||
20 | |||
21 | ** llex.c | ||
22 | Mon Jan 19 18:17:18 EDT 1998 | ||
23 | >> wrong line number (+1) in error report when file starts with "#..." | ||
24 | |||
25 | ** lstrlib.c | ||
26 | Tue Jan 27 15:27:49 EDT 1998 | ||
27 | >> formats like "%020d" were considered too big (3 digits); moreover, | ||
28 | >> some sistems limit printf to at most 500 chars, so we can limit sizes | ||
29 | >> to 2 digits (99). | ||
30 | |||
31 | ** lapi.c | ||
32 | Tue Jan 27 17:12:36 EDT 1998 | ||
33 | >> "lua_getstring" may create a new string, so should check GC | ||
34 | |||
35 | ** lstring.c / ltable.c | ||
36 | Wed Jan 28 14:48:12 EDT 1998 | ||
37 | >> tables can become full of "empty" slots, and keep growing without limits. | ||
38 | |||
39 | ** lstrlib.c | ||
40 | Mon Mar 9 15:26:09 EST 1998 | ||
41 | >> gsub('a', '(b?)%1*' ...) loops (because the capture is empty). | ||
42 | |||
43 | ** lstrlib.c | ||
44 | Mon May 18 19:20:00 EST 1998 | ||
45 | >> arguments for "format" 'x', 'X', 'o' and 'u' must be unsigned int. | ||
46 | |||
47 | |||
48 | |||
49 | ================================================================= | ||
50 | --- Version 3.1 | ||
51 | |||
52 | ** liolib.c / lauxlib.c | ||
53 | Mon Sep 7 15:57:02 EST 1998 | ||
54 | >> function "luaL_argerror" prints wrong argument number (from a user's point | ||
55 | of view) when functions have upvalues. | ||
56 | |||
57 | ** lstrlib.c | ||
58 | Tue Nov 10 17:29:36 EDT 1998 | ||
59 | >> gsub/strfind do not check whether captures are properly finished. | ||
60 | (by roberto/tomas) | ||
61 | |||
62 | ** lbuiltin.c | ||
63 | Fri Dec 18 11:22:55 EDT 1998 | ||
64 | >> "tonumber" goes crazy with negative numbers in other bases (not 10), | ||
65 | because "strtol" returns long, not unsigned long. | ||
66 | (by Visual C++) | ||
67 | |||
68 | ** lstrlib.c | ||
69 | Mon Jan 4 10:41:40 EDT 1999 | ||
70 | >> "format" does not check size of format item (such as "%00000...00000d"). | ||
71 | |||
72 | ** lapi.c | ||
73 | Wed Feb 3 14:40:21 EDT 1999 | ||
74 | >> getlocal cannot return the local itself, since lua_isstring and | ||
75 | lua_isnumber can modify it. | ||
76 | |||
77 | ** lstrlib.c | ||
78 | Thu Feb 4 17:08:50 EDT 1999 | ||
79 | >> format "%s" may break limit of "sprintf" on some machines. | ||
80 | (by Marcelo Sales) | ||
81 | |||
82 | ** lzio.c | ||
83 | Thu Mar 4 11:49:37 EST 1999 | ||
84 | >> file stream cannot call fread after EOF. | ||
85 | (by lhf) | ||
86 | |||
87 | |||
88 | |||
89 | ================================================================= | ||
90 | --- Version 3.2 (beta) | ||
91 | |||
92 | ** lstrlib.c | ||
93 | Fri Apr 30 11:10:20 EST 1999 | ||
94 | >> '$' at end of pattern was matching regular '$', too. | ||
95 | (by anna; since 2.5) | ||
96 | |||
97 | ** lbuiltin.c | ||
98 | Fri May 21 17:15:11 EST 1999 | ||
99 | >> foreach, foreachi, foreachvar points to function in stack when stack | ||
100 | can be reallocated. | ||
101 | (by tomas; since 3.2 beta) | ||
102 | |||
103 | ** lparser.c | ||
104 | Wed Jun 16 10:32:46 EST 1999 | ||
105 | >> cannot assign to unlimited variables, because it causes overflow in | ||
106 | the number of returns of a function. | ||
107 | (since 3.1) | ||
108 | |||
109 | |||
110 | |||
111 | ================================================================= | ||
112 | --- Version 3.2 | ||
113 | |||
114 | ** lmathlib.c | ||
115 | Wed Aug 18 11:28:38 EST 1999 | ||
116 | >> random(0) and random(x,0) are wrong (0 is read as no argument!). | ||
117 | (by Dave Bollinger; since 3.1) | ||
118 | |||
119 | ** lparser.c | ||
120 | Thu Sep 2 10:07:20 EST 1999 | ||
121 | >> in the (old) expression << ls->fs->f->consts[checkname(ls)] >>, checkname | ||
122 | could realloc f->consts. | ||
123 | (by Supratik Champati; since 3.2 beta) | ||
124 | |||
125 | ** lobject.c / lbuiltin.c | ||
126 | Wed Sep 8 17:41:54 EST 1999 | ||
127 | >> tonumber'e1' and tonumber(' ', x), for x!=10, gave 0 instead of nil. | ||
128 | (since 3.1) | ||
129 | |||
130 | ** lstrlib.c | ||
131 | Thu Nov 11 14:36:30 EDT 1999 | ||
132 | >> `strfind' does not handle \0 in plain search. | ||
133 | (by Jon Kleiser; since 3.1) | ||
134 | |||
135 | ** lparser.c | ||
136 | Wed Dec 29 16:05:43 EDT 1999 | ||
137 | >> return gives wrong line in debug information | ||
138 | (by lhf; since 3.2 [at least]) | ||
139 | |||
140 | ** ldo.c | ||
141 | Thu Dec 30 16:39:33 EDT 1999 | ||
142 | >> cannot reopen stdin (for binary mode) | ||
143 | (by lhf & roberto; since 3.1) | ||
144 | |||
145 | ** lapi.c | ||
146 | Thu Mar 2 09:41:53 EST 2000 | ||
147 | >> lua_settable should check stack space (it could call a T.M.) | ||
148 | (by lhf & celes; since 3.2; it was already fixed by fixed stack) | ||
149 | |||
150 | ** lparser.c | ||
151 | Mon Apr 3 09:59:06 EST 2000 | ||
152 | >> '%' should be in expfollow | ||
153 | (by Edgar Toernig; since 3.1; it was already fixed) | ||
154 | |||
155 | ** lbuiltin.c | ||
156 | Mon Apr 3 10:05:05 EST 2000 | ||
157 | >> tostring() without arguments gives seg. fault. | ||
158 | (by Edgar Toernig; since 3.0) | ||
159 | |||
160 | |||
161 | |||
162 | ================================================================= | ||
163 | --- Version 4.0 alpha | ||
164 | |||
165 | Tested with full test suites (as locked in Mon Apr 24 14:23:11 EST 2000) | ||
166 | in the following platforms: | ||
167 | * Linux - gcc, g++ | ||
168 | * AIX - gcc | ||
169 | * Solaris - gcc, cc | ||
170 | * IRIX - cc, cc-purify | ||
171 | * Windows - Visual C++ (.c e .cpp, warning level=4) | ||
172 | |||
173 | |||
174 | ** lstrlib.c | ||
175 | Tue May 2 15:27:58 EST 2000 | ||
176 | >> `strfind' gets wrong subject length when there is an offset | ||
177 | (by Jon Kleiser; since 4.0a) | ||
178 | |||
179 | ** lparser.c | ||
180 | Fri May 12 15:11:12 EST 2000 | ||
181 | >> first element in a list constructor is not adjusted to one value | ||
182 | >> (e.g. �a = {gsub('a','a','')}�) | ||
183 | (by Tomas; since 4.0a) | ||
184 | |||
185 | ** lparser.c | ||
186 | Wed May 24 14:50:16 EST 2000 | ||
187 | >> record-constructor starting with an upvalue name gets an error | ||
188 | >> (e.g. �local a; function f() x = {a=1} end�) | ||
189 | (by Edgar Toernig; since 3.1) | ||
190 | |||
191 | ** lparser.c | ||
192 | Tue Aug 29 15:56:05 EST 2000 | ||
193 | >> error message for `for' uses `while' | ||
194 | (since 4.0a; already corrected) | ||
195 | |||
196 | ** lgc.c | ||
197 | Tue Aug 29 15:57:41 EST 2000 | ||
198 | >> gc tag method for nil could call line hook | ||
199 | (by ry; since ?) | ||
200 | |||
201 | |||
202 | |||
203 | ================================================================= | ||
204 | --- Version 4.0 Beta | ||
205 | |||
206 | ** liolib.c | ||
207 | Fri Sep 22 15:12:37 EST 2000 | ||
208 | >> `read("*w")' should return nil at EOF | ||
209 | (by roberto; since 4.0b) | ||
210 | |||
211 | ** lvm.c | ||
212 | Mon Sep 25 11:47:48 EST 2000 | ||
213 | >> lua_gettable does not get key from stack top | ||
214 | (by Philip Yi; since 4.0b) | ||
215 | |||
216 | ** lgc.c | ||
217 | Mon Sep 25 11:50:48 EST 2000 | ||
218 | >> GC may crash when checking locked C closures | ||
219 | (by Philip Yi; since 4.0b) | ||
220 | |||
221 | ** lapi.c | ||
222 | Wed Sep 27 09:50:19 EST 2000 | ||
223 | >> lua_tag should return LUA_NOTAG for non-valid indices | ||
224 | (by Paul Hankin; since 4.0b) | ||
225 | |||
226 | ** llex.h / llex.c / lparser.c | ||
227 | Wed Sep 27 13:39:45 EST 2000 | ||
228 | >> parser overwrites semantic information when looking ahead | ||
229 | >> (e.g. �a = {print'foo'}�) | ||
230 | (by Edgar Toernig; since 4.0b, deriving from previous bug) | ||
231 | |||
232 | ** liolib.c | ||
233 | Thu Oct 26 10:50:46 EDT 2000 | ||
234 | >> in function `read_file', realloc() doesn't free the buffer if it can't | ||
235 | >> allocate new memory | ||
236 | (by Mauro Vezzosi; since 4.0b) | ||
237 | |||
238 | |||
239 | |||
240 | ================================================================= | ||
241 | --- Version 4.0 | ||
242 | |||
243 | ** lparser.c | ||
244 | Wed Nov 29 09:51:44 EDT 2000 | ||
245 | >> parser does not accept a `;' after a `return' | ||
246 | (by lhf; since 4.0b) | ||
247 | |||
248 | ** liolib.c | ||
249 | Fri Dec 22 15:30:42 EDT 2000 | ||
250 | >> when `read' fails it must return nil (and not no value) | ||
251 | (by cassino; since at least 3.1) | ||
252 | |||
253 | ** lstring.c/lapi.c | ||
254 | Thu Feb 1 11:55:45 EDT 2001 | ||
255 | >> lua_pushuserdata(L, NULL) is buggy | ||
256 | (by Edgar Toernig; since 4.0) | ||
257 | |||
258 | ** ldo.c | ||
259 | Fri Feb 2 14:06:40 EDT 2001 | ||
260 | >> �while 1 dostring[[print('hello\n')]] end� never reclaims memory | ||
261 | (by Andrew Paton; since 4.0b) | ||
262 | |||
263 | ** lbaselib.c | ||
264 | Tue Feb 6 11:57:13 EDT 2001 | ||
265 | >> ESC (which starts precompiled code) in C is \33, not \27 | ||
266 | (by Edgar Toernig and lhf; since 4.0b) | ||
267 | |||
268 | ** lparser.c | ||
269 | Tue Jul 10 16:59:18 EST 2001 | ||
270 | >> error message for `%a' gave wrong line number | ||
271 | (by Leonardo Constantino; since 4.0) | ||
272 | |||
273 | ** lbaselib.c | ||
274 | Fri Dec 21 15:21:05 EDT 2001 | ||
275 | >> seg. fault when rawget/rawset get extra arguments | ||
276 | (by Eric Mauger; since 4.0b) | ||
277 | |||
278 | ** lvm.c | ||
279 | Wed Jun 19 13:28:20 EST 2002 | ||
280 | >> line hook gets wrong `ar' | ||
281 | (by Daniel C. Sinclair; since 4.0.b) | ||
282 | |||
283 | ** ldo.c | ||
284 | Wed Jun 19 13:31:49 EST 2002 | ||
285 | >> `protectedparser' may run GC, and then collect `filename' | ||
286 | >> (in function `parse_file') | ||
287 | (by Alex Bilyk; since 4.0) | ||
288 | |||
289 | |||
290 | |||
291 | |||
292 | ================================================================= | ||
293 | --- Version 5.0 alpha | ||
294 | |||
295 | ** lgc.c | ||
296 | Fri Aug 30 13:49:14 EST 2002 | ||
297 | >> GC metamethod stored in a weak metatable being collected together with | ||
298 | >> userdata may not be cleared properly | ||
299 | (by Roberto; since 5.0a) | ||
300 | |||
301 | ** lapi.c | ||
302 | Thu Nov 21 11:00:00 EST 2002 | ||
303 | >> ULONG_MAX>>10 may not fit into an int | ||
304 | (by Jeff Petkau; since 4.0) | ||
305 | |||
306 | ** lparser.c | ||
307 | Fri Dec 6 17:06:40 UTC 2002 | ||
308 | >> scope of generic for variables is not sound | ||
309 | (by Gavin Wraith; since 5.0a) | ||
310 | |||
311 | |||
312 | |||
313 | |||
314 | ================================================================= | ||
315 | --- Version 5.0 beta | ||
316 | ** lbaselib.c | ||
317 | Fri Dec 20 09:53:19 UTC 2002 | ||
318 | >> `resume' was checking the wrong value for stack overflow | ||
319 | (by Maik Zimmermann; since 5.0b) | ||
320 | |||
321 | ** ldo.c | ||
322 | Thu Jan 23 11:29:06 UTC 2003 | ||
323 | >> error during garbage collection in luaD_protectedparser is not being | ||
324 | >> protected | ||
325 | (by Benoit Germain; since 5.0a) | ||
326 | |||
327 | ** ldo.c (and others) | ||
328 | Fri Feb 28 14:20:33 EST 2003 | ||
329 | >> GC metamethod calls could mess C/Lua stack syncronization | ||
330 | (by Roberto; since 5.0b) | ||
331 | |||
332 | ** lzio.h/zlio.c | ||
333 | Thu Mar 20 11:40:12 EST 2003 | ||
334 | >> zio mixes a 255 as first char in a buffer with EOZ | ||
335 | (by lhf; since 5.0a) | ||
336 | |||
337 | |||
338 | |||
339 | --]=] | ||
340 | ----------------------------------------------------------------- | ||
341 | -- Lua 5.0 (final) | ||
342 | |||
343 | Bug{ | ||
344 | what = [[lua_closethread exists only in the manual]], | ||
345 | report = [[by Nguyen Binh, 28/04/2003]], | ||
346 | patch = [[no patch; the manual is wrong]], | ||
347 | } | ||
348 | |||
349 | |||
350 | Bug{ | ||
351 | what = [[attempt to resume a running coroutine crashes Lua]], | ||
352 | example = [[ | ||
353 | function co_func (current_co) | ||
354 | coroutine.resume(co) | ||
355 | end | ||
356 | co = coroutine.create(co_func) | ||
357 | coroutine.resume(co) | ||
358 | coroutine.resume(co) --> seg. fault | ||
359 | ]], | ||
360 | report = [[by Alex Bilyk, 09/05/2003]], | ||
361 | patch = [[ | ||
362 | * ldo.c: | ||
363 | 325,326c325 | ||
364 | < if (nargs >= L->top - L->base) | ||
365 | < luaG_runerror(L, "cannot resume dead coroutine"); | ||
366 | --- | ||
367 | > lua_assert(nargs < L->top - L->base); | ||
368 | 329c328,329 | ||
369 | < else if (ci->state & CI_YIELD) { /* inside a yield? */ | ||
370 | --- | ||
371 | > else { /* inside a yield */ | ||
372 | > lua_assert(ci->state & CI_YIELD); | ||
373 | 344,345d343 | ||
374 | < else | ||
375 | < luaG_runerror(L, "cannot resume non-suspended coroutine"); | ||
376 | 351a350,358 | ||
377 | > static int resume_error (lua_State *L, const char *msg) { | ||
378 | > L->top = L->ci->base; | ||
379 | > setsvalue2s(L->top, luaS_new(L, msg)); | ||
380 | > incr_top(L); | ||
381 | > lua_unlock(L); | ||
382 | > return LUA_ERRRUN; | ||
383 | > } | ||
384 | > | ||
385 | > | ||
386 | 355a363,368 | ||
387 | > if (L->ci == L->base_ci) { | ||
388 | > if (nargs >= L->top - L->base) | ||
389 | > return resume_error(L, "cannot resume dead coroutine"); | ||
390 | > } | ||
391 | > else if (!(L->ci->state & CI_YIELD)) /* not inside a yield? */ | ||
392 | > return resume_error(L, "cannot resume non-suspended coroutine"); | ||
393 | ]], | ||
394 | } | ||
395 | |||
396 | |||
397 | Bug{ | ||
398 | what = [[file:close cannot be called without a file. (results in seg fault)]], | ||
399 | example = [[ | ||
400 | > io.stdin.close() -- correct call shold be io.stdin:close() | ||
401 | ]], | ||
402 | report = [[by Tuomo Valkonen, 27/05/2003]], | ||
403 | patch = [[ | ||
404 | * liolib.c: | ||
405 | 161c161 | ||
406 | < if (lua_isnone(L, 1)) { | ||
407 | --- | ||
408 | > if (lua_isnone(L, 1) && lua_type(L, lua_upvalueindex(1)) == LUA_TTABLE) { | ||
409 | ]], --}} | ||
410 | } | ||
411 | |||
412 | |||
413 | Bug{ | ||
414 | what = [[C functions also may have stacks larger than current top]], | ||
415 | example = [[ | ||
416 | Must recompile lua with a change in lua.c and with lua_assert defined: | ||
417 | * lua.c: | ||
418 | 381a382 | ||
419 | > lua_checkstack(l, 1000); | ||
420 | ]], | ||
421 | report = [[Alex Bilyk, 09/06/2003]], | ||
422 | patch = [[ | ||
423 | * lgc.c: | ||
424 | 247c247 | ||
425 | < if (!(ci->state & CI_C) && lim < ci->top) | ||
426 | --- | ||
427 | > if (lim < ci->top) | ||
428 | ]], | ||
429 | } | ||
430 | |||
431 | |||
432 | Bug{ | ||
433 | what = [[`pc' address is invalidated when a coroutine is suspended]], | ||
434 | example = [[ | ||
435 | function g(x) | ||
436 | coroutine.yield(x) | ||
437 | end | ||
438 | |||
439 | function f (i) | ||
440 | debug.sethook(print, "l") | ||
441 | for j=1,1000 do | ||
442 | g(i+j) | ||
443 | end | ||
444 | end | ||
445 | |||
446 | co = coroutine.wrap(f) | ||
447 | co(10) | ||
448 | pcall(co) | ||
449 | pcall(co) | ||
450 | ]], | ||
451 | report = [[Nick Trout, 07/07/2003]], | ||
452 | patch = [[ | ||
453 | * lvm.c: | ||
454 | 402,403c402,403 | ||
455 | < L->ci->u.l.pc = &pc; | ||
456 | < if (L->hookmask & LUA_MASKCALL) | ||
457 | --- | ||
458 | > if (L->hookmask & LUA_MASKCALL) { | ||
459 | > L->ci->u.l.pc = &pc; | ||
460 | 404a405 | ||
461 | > } | ||
462 | 405a407 | ||
463 | > L->ci->u.l.pc = &pc; | ||
464 | 676,678c678 | ||
465 | < lua_assert(ci->u.l.pc == &pc && | ||
466 | < ttisfunction(ci->base - 1) && | ||
467 | < (ci->state & CI_SAVEDPC)); | ||
468 | --- | ||
469 | > lua_assert(ttisfunction(ci->base - 1) && (ci->state & CI_SAVEDPC)); | ||
470 | ]] | ||
471 | } | ||
472 | |||
473 | |||
474 | Bug{ | ||
475 | what = [[userdata to be collected still counts into new GC threshold, | ||
476 | increasing memory consumption]], | ||
477 | report = [[Roberto, 25/07/2003]], | ||
478 | example = [[ | ||
479 | a = newproxy(true) | ||
480 | getmetatable(a).__gc = function () end | ||
481 | for i=1,10000000 do | ||
482 | newproxy(a) | ||
483 | if math.mod(i, 10000) == 0 then print(gcinfo()) end | ||
484 | end | ||
485 | ]], | ||
486 | patch = [[ | ||
487 | * lgc.h: | ||
488 | 18c18 | ||
489 | < void luaC_separateudata (lua_State *L); | ||
490 | --- | ||
491 | > size_t luaC_separateudata (lua_State *L); | ||
492 | |||
493 | * lgc.c: | ||
494 | 113c113,114 | ||
495 | < void luaC_separateudata (lua_State *L) { | ||
496 | --- | ||
497 | > size_t luaC_separateudata (lua_State *L) { | ||
498 | > size_t deadmem = 0; | ||
499 | 127a129 | ||
500 | > deadmem += sizeudata(gcotou(curr)->uv.len); | ||
501 | 136a139 | ||
502 | > return deadmem; | ||
503 | 390c393 | ||
504 | < static void checkSizes (lua_State *L) { | ||
505 | --- | ||
506 | > static void checkSizes (lua_State *L, size_t deadmem) { | ||
507 | 400c403 | ||
508 | < G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */ | ||
509 | --- | ||
510 | > G(L)->GCthreshold = 2*G(L)->nblocks - deadmem; /* new threshold */ | ||
511 | 454c457,458 | ||
512 | < static void mark (lua_State *L) { | ||
513 | --- | ||
514 | > static size_t mark (lua_State *L) { | ||
515 | > size_t deadmem; | ||
516 | 467c471 | ||
517 | < luaC_separateudata(L); /* separate userdata to be preserved */ | ||
518 | --- | ||
519 | > deadmem = luaC_separateudata(L); /* separate userdata to be preserved */ | ||
520 | 475a480 | ||
521 | > return deadmem; | ||
522 | 480c485 | ||
523 | < mark(L); | ||
524 | --- | ||
525 | > size_t deadmem = mark(L); | ||
526 | 482c487 | ||
527 | < checkSizes(L); | ||
528 | --- | ||
529 | > checkSizes(L, deadmem); | ||
530 | ]] | ||
531 | } | ||
532 | |||
533 | Bug{ | ||
534 | what=[[IBM AS400 (OS400) has sizeof(void *)==16, and a `%p' may generate | ||
535 | up to 60 characters in a `printf'. That causes a buffer overflow in | ||
536 | `tostring'.]], | ||
537 | |||
538 | report = [[David Burgess, 25/08/2003]], | ||
539 | |||
540 | example = [[print{}; (in an AS400 machine)]], | ||
541 | |||
542 | patch = [[ | ||
543 | * liolib.c: | ||
544 | 178c178 | ||
545 | < char buff[32]; | ||
546 | --- | ||
547 | > char buff[128]; | ||
548 | |||
549 | * lbaselib.c: | ||
550 | 327c327 | ||
551 | < char buff[64]; | ||
552 | --- | ||
553 | > char buff[128]; | ||
554 | ]] | ||
555 | } | ||
556 | |||
557 | |||
558 | Bug{ | ||
559 | what = [[syntax `local function' does not increment stack size]], | ||
560 | |||
561 | report = [[Rici Lake, 26/09/2003]], | ||
562 | |||
563 | example = [[ | ||
564 | -- must run this with precompiled code | ||
565 | local a,b,c | ||
566 | local function d () end | ||
567 | ]], | ||
568 | |||
569 | patch = [[ | ||
570 | * lparser.c: | ||
571 | 1143a1144 | ||
572 | > FuncState *fs = ls->fs; | ||
573 | 1145c1146,1147 | ||
574 | < init_exp(&v, VLOCAL, ls->fs->freereg++); | ||
575 | --- | ||
576 | > init_exp(&v, VLOCAL, fs->freereg); | ||
577 | > luaK_reserveregs(fs, 1); | ||
578 | 1148c1150,1152 | ||
579 | < luaK_storevar(ls->fs, &v, &b); | ||
580 | --- | ||
581 | > luaK_storevar(fs, &v, &b); | ||
582 | > /* debug information will only see the variable after this point! */ | ||
583 | > getlocvar(fs, fs->nactvar - 1).startpc = fs->pc; | ||
584 | ]], | ||
585 | |||
586 | } | ||
587 | |||
588 | |||
589 | Bug{ | ||
590 | |||
591 | what = [[count hook may be called without being set]], | ||
592 | |||
593 | report = [[Andreas Stenius, 06/10/2003]], | ||
594 | |||
595 | example = [[ | ||
596 | set your hooks with | ||
597 | |||
598 | lua_sethook(L, my_hook, LUA_MASKLINE | LUA_MASKRET, 1); | ||
599 | |||
600 | (It is weird to use a count > 0 without setting the count hook, | ||
601 | but it is not wrong.) | ||
602 | ]], | ||
603 | |||
604 | patch = [[ | ||
605 | * lvm.c: | ||
606 | 69c69 | ||
607 | < if (mask > LUA_MASKLINE) { /* instruction-hook set? */ | ||
608 | --- | ||
609 | > if (mask & LUA_MASKCOUNT) { /* instruction-hook set? */ | ||
610 | ]], | ||
611 | |||
612 | } | ||
613 | |||
614 | |||
615 | Bug{ | ||
616 | |||
617 | what = [[`dofile' eats one return value when called without arguments]], | ||
618 | |||
619 | report = [[Frederico Abraham, 15/01/2004]], | ||
620 | |||
621 | example = [[ | ||
622 | a,b = dofile() --< here you enter `return 1,2,3 <eof>' | ||
623 | print(a,b) --> 2 3 (should be 1 and 2) | ||
624 | ]], | ||
625 | |||
626 | patch = [[ | ||
627 | * lbaselib.c: | ||
628 | 313a314 | ||
629 | > int n = lua_gettop(L); | ||
630 | 317c318 | ||
631 | < return lua_gettop(L) - 1; | ||
632 | --- | ||
633 | > return lua_gettop(L) - n; | ||
634 | ]], | ||
635 | |||
636 | } | ||
637 | |||
638 | |||
639 | |||
640 | ----------------------------------------------------------------- | ||
641 | -- Lua 5.0.2 | ||
642 | |||
643 | Bug{ | ||
644 | what = [[string concatenation may cause arithmetic overflow, leading | ||
645 | to a buffer overflow]], | ||
646 | |||
647 | report = [[Rici Lake, 20/05/2004]], | ||
648 | |||
649 | example = [[ | ||
650 | longs = string.rep("\0", 2^25) | ||
651 | function catter(i) | ||
652 | return assert(loadstring( | ||
653 | string.format("return function(a) return a%s end", | ||
654 | string.rep("..a", i-1))))() | ||
655 | end | ||
656 | rep129 = catter(129) | ||
657 | rep129(longs) | ||
658 | ]], | ||
659 | |||
660 | patch = [[ | ||
661 | * lvm.c: | ||
662 | @@ -321,15 +321,15 @@ | ||
663 | luaG_concaterror(L, top-2, top-1); | ||
664 | } else if (tsvalue(top-1)->tsv.len > 0) { /* if len=0, do nothing */ | ||
665 | /* at least two string values; get as many as possible */ | ||
666 | - lu_mem tl = cast(lu_mem, tsvalue(top-1)->tsv.len) + | ||
667 | - cast(lu_mem, tsvalue(top-2)->tsv.len); | ||
668 | + size_t tl = tsvalue(top-1)->tsv.len; | ||
669 | char *buffer; | ||
670 | int i; | ||
671 | - while (n < total && tostring(L, top-n-1)) { /* collect total length */ | ||
672 | - tl += tsvalue(top-n-1)->tsv.len; | ||
673 | - n++; | ||
674 | + /* collect total length */ | ||
675 | + for (n = 1; n < total && tostring(L, top-n-1); n++) { | ||
676 | + size_t l = tsvalue(top-n-1)->tsv.len; | ||
677 | + if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow"); | ||
678 | + tl += l; | ||
679 | } | ||
680 | - if (tl > MAX_SIZET) luaG_runerror(L, "string size overflow"); | ||
681 | buffer = luaZ_openspace(L, &G(L)->buff, tl); | ||
682 | tl = 0; | ||
683 | for (i=n; i>0; i--) { /* concat all strings */ | ||
684 | ]] | ||
685 | } | ||
686 | |||
687 | |||
688 | Bug{ | ||
689 | what = [[lua_getupvalue and setupvalue do not check for index too small]], | ||
690 | |||
691 | report = [[Mike Pall, ?/2004]], | ||
692 | |||
693 | example = [[debug.getupvalue(function() end, 0)]], | ||
694 | |||
695 | patch = [[ | ||
696 | * lapi.c | ||
697 | 941c941 | ||
698 | < if (n > f->c.nupvalues) return NULL; | ||
699 | --- | ||
700 | > if (!(1 <= n && n <= f->c.nupvalues)) return NULL; | ||
701 | 947c947 | ||
702 | < if (n > p->sizeupvalues) return NULL; | ||
703 | --- | ||
704 | > if (!(1 <= n && n <= p->sizeupvalues)) return NULL; | ||
705 | ]] | ||
706 | } | ||
707 | |||
708 | |||
709 | Bug{ | ||
710 | what = [[values holded in open upvalues of suspended threads may be | ||
711 | incorrectly collected]], | ||
712 | |||
713 | report = [[Spencer Schumann, 31/12/2004]], | ||
714 | |||
715 | example = [[ | ||
716 | local thread_id = 0 | ||
717 | local threads = {} | ||
718 | |||
719 | function fn(thread) | ||
720 | thread_id = thread_id + 1 | ||
721 | threads[thread_id] = function() | ||
722 | thread = nil | ||
723 | end | ||
724 | coroutine.yield() | ||
725 | end | ||
726 | |||
727 | while true do | ||
728 | local thread = coroutine.create(fn) | ||
729 | coroutine.resume(thread, thread) | ||
730 | end | ||
731 | ]], | ||
732 | |||
733 | patch = [[ | ||
734 | * lgc.c: | ||
735 | 221,224c221,222 | ||
736 | < if (!u->marked) { | ||
737 | < markobject(st, &u->value); | ||
738 | < u->marked = 1; | ||
739 | < } | ||
740 | --- | ||
741 | > markobject(st, u->v); | ||
742 | > u->marked = 1; | ||
743 | ]], | ||
744 | } | ||
745 | |||
746 | |||
747 | Bug{ | ||
748 | what = [[rawset/rawget do not ignore extra arguments]], | ||
749 | |||
750 | report = [[Romulo Bahiense, 11/03/2005]], | ||
751 | |||
752 | example = [[ | ||
753 | a = {} | ||
754 | rawset(a, 1, 2, 3) | ||
755 | print(a[1], a[2]) -- should be 2 and nil | ||
756 | ]], | ||
757 | |||
758 | patch = [[ | ||
759 | * lbaselib.c: | ||
760 | 175a176 | ||
761 | > lua_settop(L, 2); | ||
762 | 183a185 | ||
763 | > lua_settop(L, 3); | ||
764 | ]], | ||
765 | } | ||
766 | |||
767 | |||
768 | Bug{ | ||
769 | what = [[weak tables that survive one collection are never collected]], | ||
770 | |||
771 | report = [[Chromix, 02/01/2006]], | ||
772 | |||
773 | example = [[ | ||
774 | a = {} | ||
775 | print(gcinfo()) | ||
776 | for i = 1, 10000 do | ||
777 | a[i] = setmetatable({}, {__mode = "v"}) | ||
778 | end | ||
779 | collectgarbage() | ||
780 | a = nil | ||
781 | collectgarbage() | ||
782 | print(gcinfo()) | ||
783 | ]], | ||
784 | |||
785 | patch = [[ | ||
786 | * lgc.c | ||
787 | @@ -366,7 +366,7 @@ | ||
788 | GCObject *curr; | ||
789 | int count = 0; /* number of collected items */ | ||
790 | while ((curr = *p) != NULL) { | ||
791 | - if (curr->gch.marked > limit) { | ||
792 | + if ((curr->gch.marked & ~(KEYWEAK | VALUEWEAK)) > limit) { | ||
793 | unmark(curr); | ||
794 | p = &curr->gch.next; | ||
795 | } | ||
796 | ]], | ||
797 | |||
798 | } | ||
799 | |||
800 | |||
801 | |||
802 | ----------------------------------------------------------------- | ||
803 | -- Lua 5.1 | ||
804 | |||
805 | Bug{ | ||
806 | what = [[In 16-bit machines, expressions and/or with numeric constants as the | ||
807 | right operand may result in weird values]], | ||
808 | |||
809 | report = [[Andreas Stenius/Kein-Hong Man, 15/03/2006]], | ||
810 | |||
811 | example = [[ | ||
812 | print(false or 0) -- on 16-bit machines | ||
813 | ]], | ||
814 | |||
815 | patch = [[ | ||
816 | * lcode.c: | ||
817 | @@ -731,17 +731,15 @@ | ||
818 | case OPR_AND: { | ||
819 | lua_assert(e1->t == NO_JUMP); /* list must be closed */ | ||
820 | luaK_dischargevars(fs, e2); | ||
821 | - luaK_concat(fs, &e1->f, e2->f); | ||
822 | - e1->k = e2->k; e1->u.s.info = e2->u.s.info; | ||
823 | - e1->u.s.aux = e2->u.s.aux; e1->t = e2->t; | ||
824 | + luaK_concat(fs, &e2->f, e1->f); | ||
825 | + *e1 = *e2; | ||
826 | break; | ||
827 | } | ||
828 | case OPR_OR: { | ||
829 | lua_assert(e1->f == NO_JUMP); /* list must be closed */ | ||
830 | luaK_dischargevars(fs, e2); | ||
831 | - luaK_concat(fs, &e1->t, e2->t); | ||
832 | - e1->k = e2->k; e1->u.s.info = e2->u.s.info; | ||
833 | - e1->u.s.aux = e2->u.s.aux; e1->f = e2->f; | ||
834 | + luaK_concat(fs, &e2->t, e1->t); | ||
835 | + *e1 = *e2; | ||
836 | break; | ||
837 | } | ||
838 | ]], | ||
839 | |||
840 | } | ||
841 | |||
842 | |||
843 | Bug{ | ||
844 | what = [[luaL_checkudata may produce wrong error message]], | ||
845 | |||
846 | report = [[Greg Falcon, 21/03/2006]], | ||
847 | |||
848 | example = [[ | ||
849 | getmetatable(io.stdin).__gc() | ||
850 | --> bad argument #1 to '__gc' (FILE* expected, got table) | ||
851 | ]], | ||
852 | |||
853 | patch = [[ | ||
854 | * lauxlib.c: | ||
855 | @@ -123,11 +123,17 @@ | ||
856 | |||
857 | LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { | ||
858 | void *p = lua_touserdata(L, ud); | ||
859 | - lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ | ||
860 | - if (p == NULL || !lua_getmetatable(L, ud) || !lua_rawequal(L, -1, -2)) | ||
861 | - luaL_typerror(L, ud, tname); | ||
862 | - lua_pop(L, 2); /* remove both metatables */ | ||
863 | - return p; | ||
864 | + if (p != NULL) { /* value is a userdata? */ | ||
865 | + if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ | ||
866 | + lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ | ||
867 | + if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */ | ||
868 | + lua_pop(L, 2); /* remove both metatables */ | ||
869 | + return p; | ||
870 | + } | ||
871 | + } | ||
872 | + } | ||
873 | + luaL_typerror(L, ud, tname); /* else error */ | ||
874 | + return NULL; /* to avoid warnings */ | ||
875 | } | ||
876 | ]] | ||
877 | |||
878 | } | ||
879 | |||
880 | |||
881 | Bug{ | ||
882 | what = [[ | ||
883 | In Windows, | ||
884 | when Lua is used in an application that also uses DirectX, | ||
885 | it may present an erractic behavior. | ||
886 | THIS IS NOT A LUA BUG! | ||
887 | The problem is that DirectX violates an ABI that Lua depends on.]], | ||
888 | |||
889 | patch = [[ | ||
890 | The simplest solution is to use DirectX with | ||
891 | the D3DCREATE_FPU_PRESERVE flag. | ||
892 | |||
893 | Otherwise, you can change the definition of lua_number2int, | ||
894 | in luaconf.h, to this one: | ||
895 | #define lua_number2int(i,d) __asm fld d __asm fistp i | ||
896 | ]], | ||
897 | |||
898 | } | ||
899 | |||
900 | |||
901 | Bug{ | ||
902 | what = [[option '%q' in string.format does not handle '\r' correctly.]], | ||
903 | |||
904 | example = [[ | ||
905 | local s = "a string with \r and \n and \r\n and \n\r" | ||
906 | local c = string.format("return %q", s) | ||
907 | assert(assert(loadstring(c))() == s) | ||
908 | ]], | ||
909 | |||
910 | patch = [[ | ||
911 | * lstrlib.c: | ||
912 | @@ -703,6 +703,10 @@ | ||
913 | luaL_addchar(b, *s); | ||
914 | break; | ||
915 | } | ||
916 | + case '\r': { | ||
917 | + luaL_addlstring(b, "\\r", 2); | ||
918 | + break; | ||
919 | + } | ||
920 | case '\0': { | ||
921 | luaL_addlstring(b, "\\000", 4); | ||
922 | break; | ||
923 | ]], | ||
924 | |||
925 | } | ||
926 | |||
927 | |||
928 | Bug{ | ||
929 | what = [[lua_dostring/lua_dofile should return any values returned | ||
930 | by the chunk]], | ||
931 | |||
932 | patch = [[ | ||
933 | * lauxlib.h: | ||
934 | @@ -108,9 +108,11 @@ | ||
935 | |||
936 | #define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) | ||
937 | |||
938 | -#define luaL_dofile(L, fn) (luaL_loadfile(L, fn) || lua_pcall(L, 0, 0, 0)) | ||
939 | +#define luaL_dofile(L, fn) \ | ||
940 | + (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) | ||
941 | |||
942 | -#define luaL_dostring(L, s) (luaL_loadstring(L, s) || lua_pcall(L, 0, 0, 0))+#define luaL_dostring(L, s) \ | ||
943 | + (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) | ||
944 | |||
945 | #define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) | ||
946 | ]], | ||
947 | |||
948 | } | ||
949 | |||
950 | |||
951 | Bug{ | ||
952 | |||
953 | what = [[garbage collector does not compensate enough for finalizers]], | ||
954 | |||
955 | patch = [[ | ||
956 | lgc.c: | ||
957 | @@ -322,4 +322,6 @@ | ||
958 | |||
959 | -static void propagateall (global_State *g) { | ||
960 | - while (g->gray) propagatemark(g); | ||
961 | +static size_t propagateall (global_State *g) { | ||
962 | + size_t m = 0; | ||
963 | + while (g->gray) m += propagatemark(g); | ||
964 | + return m; | ||
965 | } | ||
966 | @@ -542,3 +544,3 @@ | ||
967 | marktmu(g); /* mark `preserved' userdata */ | ||
968 | - propagateall(g); /* remark, to propagate `preserveness' */ | ||
969 | + udsize += propagateall(g); /* remark, to propagate `preserveness' */ | ||
970 | cleartable(g->weak); /* remove collected objects from weak tables */ | ||
971 | @@ -592,2 +594,4 @@ | ||
972 | GCTM(L); | ||
973 | + if (g->estimate > GCFINALIZECOST) | ||
974 | + g->estimate -= GCFINALIZECOST; | ||
975 | ]] | ||
976 | } | ||
977 | |||
978 | |||
979 | But{ | ||
980 | |||
981 | what = [[debug hooks may get wrong when mixed with coroutines]], | ||
982 | |||
983 | report = [[by Ivko Stanilov, 03/06/2006]], | ||
984 | |||
985 | example = [[ | ||
986 | co = coroutine.create(function (a,b) | ||
987 | coroutine.yield(a, b) | ||
988 | return b, "end" | ||
989 | end) | ||
990 | |||
991 | debug.sethook(co, function() end, "lcr") | ||
992 | coroutine.resume(co, 100, 2000) | ||
993 | coroutine.resume(co, 100, 2000) | ||
994 | ]], | ||
995 | |||
996 | patch = [[ | ||
997 | * ldo.c: | ||
998 | @@ -389,6 +389,7 @@ | ||
999 | return; | ||
1000 | } | ||
1001 | else { /* resuming from previous yield */ | ||
1002 | + L->status = 0; | ||
1003 | if (!f_isLua(ci)) { /* `common' yield? */ | ||
1004 | /* finish interrupted execution of `OP_CALL' */ | ||
1005 | lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL || | ||
1006 | @@ -399,7 +400,6 @@ | ||
1007 | else /* yielded inside a hook: just continue its execution */ | ||
1008 | L->base = L->ci->base; | ||
1009 | } | ||
1010 | - L->status = 0; | ||
1011 | luaV_execute(L, cast_int(L->ci - L->base_ci)); | ||
1012 | } | ||
1013 | ]], | ||
1014 | |||
1015 | } | ||