From 873445e2030580e2b3bcf7e9d7b619a548613af1 Mon Sep 17 00:00:00 2001 From: flynn-eye <939649107@qq.com> Date: Fri, 30 Oct 2026 13:29:51 +0900 Subject: [PATCH] io: preserve numeric string arguments when writing Write strings as supplied instead of coercing them to numbers first. CheckString preserves their whitespace and representation while retaining the existing formatting for actual numbers. Cover io.write and file:write with output and return-value regressions. --- io.go | 6 +----- io_test.go | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 io_test.go diff --git a/io.go b/io.go index 2bacd86..87124e6 100644 --- a/io.go +++ b/io.go @@ -92,11 +92,7 @@ func close(l *State) int { func write(l *State, f *os.File, argIndex int) int { var err error for argCount := l.Top(); argIndex < argCount && err == nil; argIndex++ { - if n, ok := l.ToNumber(argIndex); ok { - _, err = f.WriteString(numberToString(n)) - } else { - _, err = f.WriteString(CheckString(l, argIndex)) - } + _, err = f.WriteString(CheckString(l, argIndex)) } if err == nil { return 1 diff --git a/io_test.go b/io_test.go new file mode 100644 index 0000000..3faca8f --- /dev/null +++ b/io_test.go @@ -0,0 +1,37 @@ +package lua + +import ( + "fmt" + "os" + "path/filepath" + "testing" +) + +func TestWritePreservesNumericStrings(t *testing.T) { + for _, writer := range []string{"io.write", "f:write"} { + t.Run(writer, func(t *testing.T) { + filename := filepath.Join(t.TempDir(), "output") + l := NewState() + OpenLibraries(l) + l.PushString(filename) + l.SetGlobal("filename") + if err := DoString(l, fmt.Sprintf(` + local f = assert(io.open(filename, "wb")) + io.output(f) + assert(%s("123 ", "456 ", "Hello, ", "world!\n") == f) + assert(%s("001.20 ", " 0x10 ", "1e+02 ", 2.5, "\n") == f) + assert(f:close()) + `, writer, writer)); err != nil { + t.Fatal(err) + } + output, err := os.ReadFile(filename) + if err != nil { + t.Fatal(err) + } + const expected = "123 456 Hello, world!\n001.20 0x10 1e+02 2.5\n" + if string(output) != expected { + t.Errorf("got %q, want %q", output, expected) + } + }) + } +}