yeqown / go-qrcode

To help gophers generate QR Codes with customized styles, such as color, block size, block shape, and icon.
MIT License
567 stars 87 forks source link

[BUG] DATA RACE Issue When Calling qrcode.New from Multiple Goroutines #103

Closed mnrtks closed 7 months ago

mnrtks commented 7 months ago

Describe the bug

I am experiencing a data race issue when invoking qrcode.New concurrently from multiple goroutines. I have confirmed that this issue occurs in version v2.2.2.

To Reproduce

package main

import (
    "fmt"
    "sync"

    "github.com/yeqown/go-qrcode/v2"
)

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 10; i++ {
        wg.Add(1)

        u := fmt.Sprintf("http://example.com/dummy?id=%04d", i)
        go func(u string) {
            defer wg.Done()
            _, err := qrcode.New(u)
            if err != nil {
                panic(err)
            }
        }(u)
    }

    wg.Wait()
}
go run -race ./ ``` go run -race ./ ================== WARNING: DATA RACE Read at 0x00c000000168 by goroutine 13: github.com/yeqown/go-qrcode/v2.loadAlignmentPatternLoc() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/version.go:371 +0x60 github.com/yeqown/go-qrcode/v2.(*QRCode).prefillMatrix() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:335 +0x380 github.com/yeqown/go-qrcode/v2.(*QRCode).init() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:124 +0x5dc github.com/yeqown/go-qrcode/v2.build() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:42 +0x1d8 github.com/yeqown/go-qrcode/v2.New() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:16 +0x7c main.main.func1() work/qrcodedatarace/main.go:19 +0x78 main.main.gowrap1() work/qrcodedatarace/main.go:23 +0x54 Previous write at 0x00c000000168 by goroutine 7: github.com/yeqown/go-qrcode/v2.loadAlignmentPatternLoc() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/version.go:389 +0x1c0 github.com/yeqown/go-qrcode/v2.(*QRCode).prefillMatrix() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:335 +0x380 github.com/yeqown/go-qrcode/v2.(*QRCode).init() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:124 +0x5dc github.com/yeqown/go-qrcode/v2.build() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:42 +0x1d8 github.com/yeqown/go-qrcode/v2.New() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:16 +0x7c main.main.func1() work/qrcodedatarace/main.go:19 +0x78 main.main.gowrap1() work/qrcodedatarace/main.go:23 +0x54 Goroutine 13 (running) created at: main.main() work/qrcodedatarace/main.go:17 +0x50 Goroutine 7 (running) created at: main.main() work/qrcodedatarace/main.go:17 +0x50 ================== ================== WARNING: DATA RACE Read at 0x00c00000ed10 by goroutine 12: github.com/yeqown/go-qrcode/v2.(*QRCode).prefillMatrix() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:335 +0x538 github.com/yeqown/go-qrcode/v2.(*QRCode).init() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:124 +0x5dc github.com/yeqown/go-qrcode/v2.build() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:42 +0x1d8 github.com/yeqown/go-qrcode/v2.New() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:16 +0x7c main.main.func1() work/qrcodedatarace/main.go:19 +0x78 main.main.gowrap1() work/qrcodedatarace/main.go:23 +0x54 Previous write at 0x00c00000ed10 by goroutine 7: github.com/yeqown/go-qrcode/v2.loadAlignmentPatternLoc() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/version.go:386 +0x33c github.com/yeqown/go-qrcode/v2.(*QRCode).prefillMatrix() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:335 +0x380 github.com/yeqown/go-qrcode/v2.(*QRCode).init() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:124 +0x5dc github.com/yeqown/go-qrcode/v2.build() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:42 +0x1d8 github.com/yeqown/go-qrcode/v2.New() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:16 +0x7c main.main.func1() work/qrcodedatarace/main.go:19 +0x78 main.main.gowrap1() work/qrcodedatarace/main.go:23 +0x54 Goroutine 12 (running) created at: main.main() work/qrcodedatarace/main.go:17 +0x50 Goroutine 7 (running) created at: main.main() work/qrcodedatarace/main.go:17 +0x50 ================== ================== WARNING: DATA RACE Read at 0x00c00009c180 by goroutine 8: runtime.mapaccess1_fast64() .local/share/mise/installs/go/1.22.1/go/src/runtime/map_fast64.go:13 +0x1bc github.com/yeqown/go-qrcode/v2.loadAlignmentPatternLoc() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/version.go:371 +0x54 github.com/yeqown/go-qrcode/v2.(*QRCode).prefillMatrix() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:335 +0x380 github.com/yeqown/go-qrcode/v2.(*QRCode).init() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:124 +0x5dc github.com/yeqown/go-qrcode/v2.build() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:42 +0x1d8 github.com/yeqown/go-qrcode/v2.New() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:16 +0x7c main.main.func1() work/qrcodedatarace/main.go:19 +0x78 main.main.gowrap1() work/qrcodedatarace/main.go:23 +0x54 Previous write at 0x00c00009c180 by goroutine 7: runtime.mapaccess2_fast64() .local/share/mise/installs/go/1.22.1/go/src/runtime/map_fast64.go:53 +0x1cc github.com/yeqown/go-qrcode/v2.loadAlignmentPatternLoc() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/version.go:389 +0x1b4 github.com/yeqown/go-qrcode/v2.(*QRCode).prefillMatrix() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:335 +0x380 github.com/yeqown/go-qrcode/v2.(*QRCode).init() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:124 +0x5dc github.com/yeqown/go-qrcode/v2.build() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:42 +0x1d8 github.com/yeqown/go-qrcode/v2.New() pkg/mod/github.com/yeqown/go-qrcode/v2@v2.2.2/qrcode.go:16 +0x7c main.main.func1() work/qrcodedatarace/main.go:19 +0x78 main.main.gowrap1() work/qrcodedatarace/main.go:23 +0x54 Goroutine 8 (running) created at: main.main() work/qrcodedatarace/main.go:17 +0x50 Goroutine 7 (running) created at: main.main() work/qrcodedatarace/main.go:17 +0x50 ================== Found 3 data race(s) exit status 66 ```

Expected behavior

I expect that no data races occur.

Screenshots

Additional context

yeqown commented 7 months ago

@mnrtks could you make a PR to fix this? The data race has pointed to the root cause as the loadAlignmentPatternLoc function.

mnrtks commented 7 months ago

@yeqown I have created a pull request (#104) to fix the data race issue in the loadAlignmentPatternLoc function. Please review it.