summaryrefslogtreecommitdiff
path: root/bugs
diff options
context:
space:
mode:
Diffstat (limited to 'bugs')
-rw-r--r--bugs1015
1 files changed, 0 insertions, 1015 deletions
diff --git a/bugs b/bugs
deleted file mode 100644
index a9f53823..00000000
--- a/bugs
+++ /dev/null
@@ -1,1015 +0,0 @@
1--[=[
2** lua.stx / llex.c
3Tue 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
13Thu Jan 15 14:34:58 EDT 1998
14>> must include "stdlib.h" (for "exit()").
15
16** lbuiltin.c / lobject.h
17Thu Jan 15 14:34:58 EDT 1998
18>> MAX_WORD may be bigger than MAX_INT
19(by lhf)
20
21** llex.c
22Mon Jan 19 18:17:18 EDT 1998
23>> wrong line number (+1) in error report when file starts with "#..."
24
25** lstrlib.c
26Tue 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
32Tue 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
36Wed Jan 28 14:48:12 EDT 1998
37>> tables can become full of "empty" slots, and keep growing without limits.
38
39** lstrlib.c
40Mon Mar 9 15:26:09 EST 1998
41>> gsub('a', '(b?)%1*' ...) loops (because the capture is empty).
42
43** lstrlib.c
44Mon 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
53Mon Sep 7 15:57:02 EST 1998
54>> function "luaL_argerror" prints wrong argument number (from a user's point
55of view) when functions have upvalues.
56
57** lstrlib.c
58Tue 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
63Fri Dec 18 11:22:55 EDT 1998
64>> "tonumber" goes crazy with negative numbers in other bases (not 10),
65because "strtol" returns long, not unsigned long.
66(by Visual C++)
67
68** lstrlib.c
69Mon Jan 4 10:41:40 EDT 1999
70>> "format" does not check size of format item (such as "%00000...00000d").
71
72** lapi.c
73Wed Feb 3 14:40:21 EDT 1999
74>> getlocal cannot return the local itself, since lua_isstring and
75lua_isnumber can modify it.
76
77** lstrlib.c
78Thu 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
83Thu 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
93Fri 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
98Fri May 21 17:15:11 EST 1999
99>> foreach, foreachi, foreachvar points to function in stack when stack
100can be reallocated.
101(by tomas; since 3.2 beta)
102
103** lparser.c
104Wed Jun 16 10:32:46 EST 1999
105>> cannot assign to unlimited variables, because it causes overflow in
106the number of returns of a function.
107(since 3.1)
108
109
110
111=================================================================
112--- Version 3.2
113
114** lmathlib.c
115Wed 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
120Thu Sep 2 10:07:20 EST 1999
121>> in the (old) expression << ls->fs->f->consts[checkname(ls)] >>, checkname
122could realloc f->consts.
123(by Supratik Champati; since 3.2 beta)
124
125** lobject.c / lbuiltin.c
126Wed 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
131Thu 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
136Wed 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
141Thu 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
146Thu 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
151Mon 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
156Mon 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
165Tested with full test suites (as locked in Mon Apr 24 14:23:11 EST 2000)
166in 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
175Tue 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
180Fri 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
186Wed 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
192Tue Aug 29 15:56:05 EST 2000
193>> error message for `for' uses `while'
194(since 4.0a; already corrected)
195
196** lgc.c
197Tue 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
207Fri 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
212Mon 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
217Mon 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
222Wed 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
227Wed 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
233Thu 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
244Wed 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
249Fri 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
254Thu 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
259Fri 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
264Tue 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
269Tue 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
274Fri 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
279Wed 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
284Wed 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
296Fri 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
302Thu 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
307Fri 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
317Fri 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
322Thu 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)
328Fri 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
333Thu 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
343Bug{
344what = [[lua_closethread exists only in the manual]],
345report = [[by Nguyen Binh, 28/04/2003]],
346patch = [[no patch; the manual is wrong]],
347}
348
349
350Bug{
351what = [[attempt to resume a running coroutine crashes Lua]],
352example = [[
353function co_func (current_co)
354 coroutine.resume(co)
355end
356co = coroutine.create(co_func)
357coroutine.resume(co)
358coroutine.resume(co) --> seg. fault
359]],
360report = [[by Alex Bilyk, 09/05/2003]],
361patch = [[
362* ldo.c:
363325,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);
368329c328,329
369< else if (ci->state & CI_YIELD) { /* inside a yield? */
370---
371> else { /* inside a yield */
372> lua_assert(ci->state & CI_YIELD);
373344,345d343
374< else
375< luaG_runerror(L, "cannot resume non-suspended coroutine");
376351a350,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>
386355a363,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
397Bug{
398what = [[file:close cannot be called without a file. (results in seg fault)]],
399example = [[
400> io.stdin.close() -- correct call shold be io.stdin:close()
401]],
402report = [[by Tuomo Valkonen, 27/05/2003]],
403patch = [[
404* liolib.c:
405161c161
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
413Bug{
414what = [[C functions also may have stacks larger than current top]],
415example = [[
416Must recompile lua with a change in lua.c and with lua_assert defined:
417* lua.c:
418381a382
419> lua_checkstack(l, 1000);
420]],
421report = [[Alex Bilyk, 09/06/2003]],
422patch = [[
423* lgc.c:
424247c247
425< if (!(ci->state & CI_C) && lim < ci->top)
426---
427> if (lim < ci->top)
428]],
429}
430
431
432Bug{
433what = [[`pc' address is invalidated when a coroutine is suspended]],
434example = [[
435function g(x)
436 coroutine.yield(x)
437end
438
439function f (i)
440 debug.sethook(print, "l")
441 for j=1,1000 do
442 g(i+j)
443 end
444end
445
446co = coroutine.wrap(f)
447co(10)
448pcall(co)
449pcall(co)
450]],
451report = [[Nick Trout, 07/07/2003]],
452patch = [[
453* lvm.c:
454402,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;
460404a405
461> }
462405a407
463> L->ci->u.l.pc = &pc;
464676,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
474Bug{
475what = [[userdata to be collected still counts into new GC threshold,
476increasing memory consumption]],
477report = [[Roberto, 25/07/2003]],
478example = [[
479a = newproxy(true)
480getmetatable(a).__gc = function () end
481for i=1,10000000 do
482 newproxy(a)
483 if math.mod(i, 10000) == 0 then print(gcinfo()) end
484end
485]],
486patch = [[
487* lgc.h:
48818c18
489< void luaC_separateudata (lua_State *L);
490---
491> size_t luaC_separateudata (lua_State *L);
492
493* lgc.c:
494113c113,114
495< void luaC_separateudata (lua_State *L) {
496---
497> size_t luaC_separateudata (lua_State *L) {
498> size_t deadmem = 0;
499127a129
500> deadmem += sizeudata(gcotou(curr)->uv.len);
501136a139
502> return deadmem;
503390c393
504< static void checkSizes (lua_State *L) {
505---
506> static void checkSizes (lua_State *L, size_t deadmem) {
507400c403
508< G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */
509---
510> G(L)->GCthreshold = 2*G(L)->nblocks - deadmem; /* new threshold */
511454c457,458
512< static void mark (lua_State *L) {
513---
514> static size_t mark (lua_State *L) {
515> size_t deadmem;
516467c471
517< luaC_separateudata(L); /* separate userdata to be preserved */
518---
519> deadmem = luaC_separateudata(L); /* separate userdata to be preserved */
520475a480
521> return deadmem;
522480c485
523< mark(L);
524---
525> size_t deadmem = mark(L);
526482c487
527< checkSizes(L);
528---
529> checkSizes(L, deadmem);
530]]
531}
532
533Bug{
534what=[[IBM AS400 (OS400) has sizeof(void *)==16, and a `%p' may generate
535up to 60 characters in a `printf'. That causes a buffer overflow in
536`tostring'.]],
537
538report = [[David Burgess, 25/08/2003]],
539
540example = [[print{}; (in an AS400 machine)]],
541
542patch = [[
543* liolib.c:
544178c178
545< char buff[32];
546---
547> char buff[128];
548
549* lbaselib.c:
550327c327
551< char buff[64];
552---
553> char buff[128];
554]]
555}
556
557
558Bug{
559what = [[syntax `local function' does not increment stack size]],
560
561report = [[Rici Lake, 26/09/2003]],
562
563example = [[
564-- must run this with precompiled code
565local a,b,c
566local function d () end
567]],
568
569patch = [[
570* lparser.c:
5711143a1144
572> FuncState *fs = ls->fs;
5731145c1146,1147
574< init_exp(&v, VLOCAL, ls->fs->freereg++);
575---
576> init_exp(&v, VLOCAL, fs->freereg);
577> luaK_reserveregs(fs, 1);
5781148c1150,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
589Bug{
590
591what = [[count hook may be called without being set]],
592
593report = [[Andreas Stenius, 06/10/2003]],
594
595example = [[
596set 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,
601but it is not wrong.)
602]],
603
604patch = [[
605* lvm.c:
60669c69
607< if (mask > LUA_MASKLINE) { /* instruction-hook set? */
608---
609> if (mask & LUA_MASKCOUNT) { /* instruction-hook set? */
610]],
611
612}
613
614
615Bug{
616
617what = [[`dofile' eats one return value when called without arguments]],
618
619report = [[Frederico Abraham, 15/01/2004]],
620
621example = [[
622a,b = dofile() --< here you enter `return 1,2,3 <eof>'
623print(a,b) --> 2 3 (should be 1 and 2)
624]],
625
626patch = [[
627* lbaselib.c:
628313a314
629> int n = lua_gettop(L);
630317c318
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
643Bug{
644what = [[string concatenation may cause arithmetic overflow, leading
645to a buffer overflow]],
646
647report = [[Rici Lake, 20/05/2004]],
648
649example = [[
650longs = string.rep("\0", 2^25)
651function catter(i)
652 return assert(loadstring(
653 string.format("return function(a) return a%s end",
654 string.rep("..a", i-1))))()
655end
656rep129 = catter(129)
657rep129(longs)
658]],
659
660patch = [[
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
688Bug{
689what = [[lua_getupvalue and setupvalue do not check for index too small]],
690
691report = [[Mike Pall, ?/2004]],
692
693example = [[debug.getupvalue(function() end, 0)]],
694
695patch = [[
696* lapi.c
697941c941
698< if (n > f->c.nupvalues) return NULL;
699---
700> if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
701947c947
702< if (n > p->sizeupvalues) return NULL;
703---
704> if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
705]]
706}
707
708
709Bug{
710what = [[values holded in open upvalues of suspended threads may be
711incorrectly collected]],
712
713report = [[Spencer Schumann, 31/12/2004]],
714
715example = [[
716local thread_id = 0
717local threads = {}
718
719function fn(thread)
720 thread_id = thread_id + 1
721 threads[thread_id] = function()
722 thread = nil
723 end
724 coroutine.yield()
725end
726
727while true do
728 local thread = coroutine.create(fn)
729 coroutine.resume(thread, thread)
730end
731]],
732
733patch = [[
734* lgc.c:
735221,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
747Bug{
748what = [[rawset/rawget do not ignore extra arguments]],
749
750report = [[Romulo Bahiense, 11/03/2005]],
751
752example = [[
753a = {}
754rawset(a, 1, 2, 3)
755print(a[1], a[2]) -- should be 2 and nil
756]],
757
758patch = [[
759* lbaselib.c:
760175a176
761> lua_settop(L, 2);
762183a185
763> lua_settop(L, 3);
764]],
765}
766
767
768Bug{
769what = [[weak tables that survive one collection are never collected]],
770
771report = [[Chromix, 02/01/2006]],
772
773example = [[
774a = {}
775print(gcinfo())
776for i = 1, 10000 do
777 a[i] = setmetatable({}, {__mode = "v"})
778end
779collectgarbage()
780a = nil
781collectgarbage()
782print(gcinfo())
783]],
784
785patch = [[
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
805Bug{
806what = [[In 16-bit machines, expressions and/or with numeric constants as the
807right operand may result in weird values]],
808
809report = [[Andreas Stenius/Kein-Hong Man, 15/03/2006]],
810
811example = [[
812print(false or 0) -- on 16-bit machines
813]],
814
815patch = [[
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
843Bug{
844what = [[luaL_checkudata may produce wrong error message]],
845
846report = [[Greg Falcon, 21/03/2006]],
847
848example = [[
849getmetatable(io.stdin).__gc()
850 --> bad argument #1 to '__gc' (FILE* expected, got table)
851]],
852
853patch = [[
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
881Bug{
882what = [[
883In Windows,
884when Lua is used in an application that also uses DirectX,
885it may present an erractic behavior.
886THIS IS NOT A LUA BUG!
887The problem is that DirectX violates an ABI that Lua depends on.]],
888
889patch = [[
890The simplest solution is to use DirectX with
891the D3DCREATE_FPU_PRESERVE flag.
892
893Otherwise, you can change the definition of lua_number2int,
894in luaconf.h, to this one:
895#define lua_number2int(i,d) __asm fld d __asm fistp i
896]],
897
898}
899
900
901Bug{
902what = [[option '%q' in string.format does not handle '\r' correctly.]],
903
904example = [[
905local s = "a string with \r and \n and \r\n and \n\r"
906local c = string.format("return %q", s)
907assert(assert(loadstring(c))() == s)
908]],
909
910patch = [[
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
928Bug{
929what = [[lua_dostring/lua_dofile should return any values returned
930by the chunk]],
931
932patch = [[
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
951Bug{
952
953what = [[garbage collector does not compensate enough for finalizers]],
954
955patch = [[
956lgc.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
979But{
980
981what = [[debug hooks may get wrong when mixed with coroutines]],
982
983report = [[by Ivko Stanilov, 03/06/2006]],
984
985example = [[
986co = coroutine.create(function (a,b)
987 coroutine.yield(a, b)
988 return b, "end"
989end)
990
991debug.sethook(co, function() end, "lcr")
992coroutine.resume(co, 100, 2000)
993coroutine.resume(co, 100, 2000)
994]],
995
996patch = [[
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}