Skip to content

Commit 44ded6a

Browse files
committed
fix: stack overflow in table.concat function
The previous implementation of tableConcat was pushing all values and separators onto the Lua stack before concatenating them, which caused stack overflow with large tables. This fix changes the implementation to build the result string incrementally rather than pushing all values onto the stack first, preventing stack overflow with large tables. Example that would previously fail but now works correctly: ``` package main import "github.com/yuin/gopher-lua" func main() { var L *lua.LState var err error L = lua.NewState() defer L.Close() err = L.DoString(` local t = {} for i = 1, 10000 do t[i] = tostring(i) end local s = table.concat(t, ',') `) if err != nil { println(err.Error()) } } ```
1 parent ccacf66 commit 44ded6a

1 file changed

Lines changed: 5 additions & 5 deletions

File tree

tablelib.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package lua
22

33
import (
44
"sort"
5+
"strings"
56
)
67

78
func OpenTable(L *LState) int {
@@ -66,19 +67,18 @@ func tableConcat(L *LState) int {
6667
L.Push(emptyLString)
6768
return 1
6869
}
69-
//TODO should flushing?
70-
retbottom := L.GetTop()
70+
var sb strings.Builder
7171
for ; i <= j; i++ {
7272
v := tbl.RawGetInt(i)
7373
if !LVCanConvToString(v) {
7474
L.RaiseError("invalid value (%s) at index %d in table for concat", v.Type().String(), i)
7575
}
76-
L.Push(v)
76+
sb.WriteString(LVAsString(v))
7777
if i != j {
78-
L.Push(sep)
78+
sb.WriteString(LVAsString(sep))
7979
}
8080
}
81-
L.Push(stringConcat(L, L.GetTop()-retbottom, L.reg.Top()-1))
81+
L.Push(LString(sb.String()))
8282
return 1
8383
}
8484

0 commit comments

Comments
 (0)