Skip to content

fix: prevent nil pointer panic when piping input to sqlcmd (fixes #607)#640

Merged
dlevy-msft-sql merged 1 commit intomicrosoft:mainfrom
dlevy-msft-sql:fix/stdin-pipe-panic-607
Jan 27, 2026
Merged

fix: prevent nil pointer panic when piping input to sqlcmd (fixes #607)#640
dlevy-msft-sql merged 1 commit intomicrosoft:mainfrom
dlevy-msft-sql:fix/stdin-pipe-panic-607

Conversation

@dlevy-msft-sql
Copy link
Contributor

Summary

Fixes #607 - nil pointer dereference when piping input to sqlcmd with ODBC-compatible flags.

Problem

When running:

"select @@servername" | sqlcmd -G -S server.database.windows.net -d mydb

A panic occurred in scanNext() due to a nil Console pointer.

Root Cause

In cmd/sqlcmd/sqlcmd.go, when using ODBC-compat flags with piped stdin, the isConsoleInitializationRequired() function returned false because stdin was detected as redirected and no password was required. This caused sqlcmd.New(nil, ...) to be called with a nil Console.

Solution

Added a condition in isConsoleInitializationRequired() to return needsConsole = true when stdin is redirected and no input file or query is specified.

Changes

  1. cmd/sqlcmd/sqlcmd.go - Added condition for piped stdin
  2. cmd/sqlcmd/stdin_console_test.go - Added TestPipedInputRequiresConsole test
  3. README.md - Added documentation section showing how to pipe input to sqlcmd

Testing

  • Unit tests pass
  • Manual testing with PowerShell piped input works
  • Linter passes

@dlevy-msft-sql dlevy-msft-sql self-assigned this Jan 26, 2026
@dlevy-msft-sql dlevy-msft-sql added Size: S Small issue (less than one week effort) go Pull requests that update go code labels Jan 26, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a nil pointer dereference panic (#607) that occurred when piping input to sqlcmd with ODBC-compatible flags (e.g., -G for Azure AD authentication). The panic happened because the Console object was not initialized when stdin was redirected/piped and no password prompt was needed, causing a crash when trying to read from stdin.

Changes:

  • Modified isConsoleInitializationRequired() to return needsConsole = true when stdin is redirected and no input file, query, or ChangePasswordAndExit is specified
  • Updated existing test expectations to reflect the fix and added a new comprehensive test for piped input scenarios
  • Added README documentation showing how to pipe input to sqlcmd

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
cmd/sqlcmd/sqlcmd.go Added condition to detect piped stdin and require console initialization to prevent nil pointer dereference
cmd/sqlcmd/stdin_console_test.go Updated existing test expectations and added comprehensive test case for piped input scenarios including edge case with ChangePasswordAndExit
README.md Added new documentation section with examples of piping input to sqlcmd in PowerShell and Bash

…rosoft#607)

When stdin is redirected (piped input) with ODBC-compat flags like -G,
the Console was not being initialized, causing a nil pointer dereference
in scanNext() when calling s.lineIo.Readline().

The fix ensures isConsoleInitializationRequired() returns true when
stdin is redirected and no input file or query is specified, so that
console.NewConsole() is called to handle the piped input.

Changes:
- Add condition in isConsoleInitializationRequired() for piped stdin
- Add test case using os.Pipe() to verify piped input detection
- Add README section documenting how to pipe input to sqlcmd
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@shueybubbles
Copy link
Collaborator

feels like we need some tests that build the app in /cmd/modern and run it. This case is a good one to start with.

Copy link
Collaborator

@shueybubbles shueybubbles left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@dlevy-msft-sql dlevy-msft-sql merged commit e31f42f into microsoft:main Jan 27, 2026
15 checks passed
dlevy-msft-sql added a commit to dlevy-msft-sql/go-sqlcmd that referenced this pull request Jan 27, 2026
Add e2e tests that build the sqlcmd binary and exercise real-world scenarios:

- TestE2E_Help: verifies --help flag works
- TestE2E_Version: verifies --version flag works
- TestE2E_PipedInput_NoPanic: regression test for microsoft#607 (piped input panic)
- TestE2E_PipedInput_EmptyInput: empty piped input doesn't panic
- TestE2E_InvalidFlag: invalid flags produce helpful errors
- TestE2E_QueryFlag_NoServer: -Q flag without server doesn't panic
- TestE2E_InputFile_NotFound: missing input file errors gracefully
- TestE2E_PipedInput_WithStdinReader: GO batches in piped input work

The tests build the binary once and reuse it for all tests.
Non-connection tests can run anywhere without a SQL Server.

Addresses feedback from @shueybubbles in PR microsoft#640.
@dlevy-msft-sql dlevy-msft-sql added this to the v1.9.2 milestone Jan 27, 2026
dlevy-msft-sql added a commit to dlevy-msft-sql/go-sqlcmd that referenced this pull request Jan 27, 2026
Add e2e tests that build the sqlcmd binary and exercise real-world scenarios:

Non-connection tests (always run):
- TestE2E_Help: verifies --help flag works
- TestE2E_Version: verifies --version flag works
- TestE2E_PipedInput_NoPanic: regression test for microsoft#607 (piped input panic)
- TestE2E_PipedInput_EmptyInput: empty piped input doesn't panic
- TestE2E_InvalidFlag: invalid flags produce helpful errors
- TestE2E_QueryFlag_NoServer: -Q flag without server doesn't panic
- TestE2E_InputFile_NotFound: missing input file errors gracefully
- TestE2E_PipedInput_WithStdinReader: GO batches in piped input work

Live connection tests (run when SQLCMDSERVER is set):
- TestE2E_PipedInput_LiveConnection: piped SQL with real server
- TestE2E_QueryFlag_LiveConnection: -Q flag with real server
- TestE2E_InputFile_LiveConnection: -i flag with real server

The tests build the binary once and reuse it for all tests.
Live connection tests use SQLCMDSERVER, SQLCMDUSER, SQLCMDPASSWORD env vars.

Addresses feedback from @shueybubbles in PR microsoft#640.
dlevy-msft-sql added a commit to dlevy-msft-sql/go-sqlcmd that referenced this pull request Jan 27, 2026
Add e2e tests that build the sqlcmd binary and exercise real-world scenarios:

Non-connection tests (always run):
- TestE2E_Help: verifies --help flag works
- TestE2E_Version: verifies --version flag works
- TestE2E_PipedInput_NoPanic: regression test for microsoft#607 (piped input panic)
- TestE2E_PipedInput_EmptyInput: empty piped input doesn't panic
- TestE2E_InvalidFlag: invalid flags produce helpful errors
- TestE2E_QueryFlag_NoServer: -Q flag without server doesn't panic
- TestE2E_InputFile_NotFound: missing input file errors gracefully
- TestE2E_PipedInput_WithStdinReader: GO batches in piped input work

Live connection tests (run when SQLCMDSERVER is set):
- TestE2E_PipedInput_LiveConnection: piped SQL with real server
- TestE2E_QueryFlag_LiveConnection: -Q flag with real server
- TestE2E_InputFile_LiveConnection: -i flag with real server

The tests build the binary once and reuse it for all tests.
Live connection tests use SQLCMDSERVER, SQLCMDUSER, SQLCMDPASSWORD env vars.

Addresses feedback from @shueybubbles in PR microsoft#640.
dlevy-msft-sql added a commit to dlevy-msft-sql/go-sqlcmd that referenced this pull request Jan 27, 2026
Add e2e tests that build the sqlcmd binary and exercise real-world scenarios:

Non-connection tests (always run):
- TestE2E_Help: verifies --help flag works
- TestE2E_Version: verifies --version flag works
- TestE2E_PipedInput_NoPanic: regression test for microsoft#607 (piped input panic)
- TestE2E_PipedInput_EmptyInput: empty piped input doesn't panic
- TestE2E_InvalidFlag: invalid flags produce helpful errors
- TestE2E_QueryFlag_NoServer: -Q flag without server doesn't panic
- TestE2E_InputFile_NotFound: missing input file errors gracefully
- TestE2E_PipedInput_WithStdinReader: GO batches in piped input work

Live connection tests (run when SQLCMDSERVER is set):
- TestE2E_PipedInput_LiveConnection: piped SQL with real server
- TestE2E_QueryFlag_LiveConnection: -Q flag with real server
- TestE2E_InputFile_LiveConnection: -i flag with real server

The tests build the binary once and reuse it for all tests.
Live connection tests use SQLCMDSERVER, SQLCMDUSER, SQLCMDPASSWORD env vars.

Addresses feedback from @shueybubbles in PR microsoft#640.
dlevy-msft-sql added a commit to dlevy-msft-sql/go-sqlcmd that referenced this pull request Jan 27, 2026
Add e2e tests that build the sqlcmd binary and exercise real-world scenarios:

Non-connection tests (always run):
- TestE2E_Help: verifies --help flag works
- TestE2E_Version: verifies --version flag works
- TestE2E_PipedInput_NoPanic: regression test for microsoft#607 (piped input panic)
- TestE2E_PipedInput_EmptyInput: empty piped input doesn't panic
- TestE2E_InvalidFlag: invalid flags produce helpful errors
- TestE2E_QueryFlag_NoServer: -Q flag without server doesn't panic
- TestE2E_InputFile_NotFound: missing input file errors gracefully
- TestE2E_PipedInput_WithStdinReader: GO batches in piped input work

Live connection tests (run when SQLCMDSERVER is set):
- TestE2E_PipedInput_LiveConnection: piped SQL with real server
- TestE2E_QueryFlag_LiveConnection: -Q flag with real server
- TestE2E_InputFile_LiveConnection: -i flag with real server

The tests build the binary once and reuse it for all tests.
Live connection tests use SQLCMDSERVER, SQLCMDUSER, SQLCMDPASSWORD env vars.

Addresses feedback from @shueybubbles in PR microsoft#640.
dlevy-msft-sql added a commit to dlevy-msft-sql/go-sqlcmd that referenced this pull request Jan 27, 2026
Add e2e tests that build the sqlcmd binary and exercise real-world scenarios:

Non-connection tests (always run):
- TestE2E_Help: verifies --help flag works
- TestE2E_Version: verifies --version flag works
- TestE2E_PipedInput_NoPanic: regression test for microsoft#607 (piped input panic)
- TestE2E_PipedInput_EmptyInput: empty piped input doesn't panic
- TestE2E_InvalidFlag: invalid flags produce helpful errors
- TestE2E_QueryFlag_NoServer: -Q flag without server doesn't panic
- TestE2E_InputFile_NotFound: missing input file errors gracefully
- TestE2E_PipedInput_WithStdinReader: GO batches in piped input work

Live connection tests (run when SQLCMDSERVER is set):
- TestE2E_PipedInput_LiveConnection: piped SQL with real server
- TestE2E_QueryFlag_LiveConnection: -Q flag with real server
- TestE2E_InputFile_LiveConnection: -i flag with real server

The tests build the binary once and reuse it for all tests.
Live connection tests use SQLCMDSERVER, SQLCMDUSER, SQLCMDPASSWORD env vars.

Addresses feedback from @shueybubbles in PR microsoft#640.
dlevy-msft-sql added a commit to dlevy-msft-sql/go-sqlcmd that referenced this pull request Jan 27, 2026
Add e2e tests that build the sqlcmd binary and exercise real-world scenarios:

Non-connection tests (always run):
- TestE2E_Help: verifies --help flag works
- TestE2E_Version: verifies --version flag works
- TestE2E_PipedInput_NoPanic: regression test for microsoft#607 (piped input panic)
- TestE2E_PipedInput_EmptyInput: empty piped input doesn't panic
- TestE2E_InvalidFlag: invalid flags produce helpful errors
- TestE2E_QueryFlag_NoServer: -Q flag without server doesn't panic
- TestE2E_InputFile_NotFound: missing input file errors gracefully
- TestE2E_PipedInput_WithStdinReader: GO batches in piped input work

Live connection tests (run when SQLCMDSERVER is set):
- TestE2E_PipedInput_LiveConnection: piped SQL with real server
- TestE2E_QueryFlag_LiveConnection: -Q flag with real server
- TestE2E_InputFile_LiveConnection: -i flag with real server

The tests build the binary once and reuse it for all tests.
Live connection tests use SQLCMDSERVER, SQLCMDUSER, SQLCMDPASSWORD env vars.

Addresses feedback from @shueybubbles in PR microsoft#640.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

go Pull requests that update go code Size: S Small issue (less than one week effort)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sqlcmd panic when run inside emacs

3 participants