-
Notifications
You must be signed in to change notification settings - Fork 1.1k
fix(db): persist CPE column in postgres and mysql writers #2494
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -743,11 +743,10 @@ func (r *Runner) streamInput() (chan string, error) { | |
| return | ||
| } | ||
| } else { | ||
| fchan, err := fileutil.ReadFile(r.options.InputFile) | ||
| if err != nil { | ||
| return | ||
| } | ||
| for item := range fchan { | ||
| for item, err := range fileutil.Lines(r.options.InputFile) { | ||
| if err != nil { | ||
| return | ||
| } | ||
|
Comment on lines
+746
to
+749
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do not swallow stream read errors silently. At Line 748, Line 765, and Line 778, read errors cause an immediate return with no log/error signal. That can truncate scans silently and is very hard to diagnose. Proposed fix@@
- for item, err := range fileutil.Lines(r.options.InputFile) {
+ for item, err := range fileutil.Lines(r.options.InputFile) {
if err != nil {
+ gologger.Error().Msgf("Could not read input file '%s': %s\n", r.options.InputFile, err)
return
}
@@
- for item, err := range fileutil.Lines(file) {
+ for item, err := range fileutil.Lines(file) {
if err != nil {
+ gologger.Error().Msgf("Could not read input file '%s': %s\n", file, err)
return
}
@@
- for item, err := range fileutil.LinesReader(os.Stdin) {
+ for item, err := range fileutil.LinesReader(os.Stdin) {
if err != nil {
+ gologger.Error().Msgf("Could not read input from stdin: %s\n", err)
return
}Also applies to: 763-766, 776-779 🤖 Prompt for AI Agents |
||
| if r.options.SkipDedupe || r.testAndSet(item) { | ||
| if !trySend(item) { | ||
| return | ||
|
|
@@ -761,11 +760,10 @@ func (r *Runner) streamInput() (chan string, error) { | |
| gologger.Fatal().Msgf("No input provided: %s", err) | ||
| } | ||
| for _, file := range files { | ||
| fchan, err := fileutil.ReadFile(file) | ||
| if err != nil { | ||
| return | ||
| } | ||
| for item := range fchan { | ||
| for item, err := range fileutil.Lines(file) { | ||
| if err != nil { | ||
| return | ||
| } | ||
| if r.options.SkipDedupe || r.testAndSet(item) { | ||
| if !trySend(item) { | ||
| return | ||
|
|
@@ -775,11 +773,10 @@ func (r *Runner) streamInput() (chan string, error) { | |
| } | ||
| } | ||
| if fileutil.HasStdin() { | ||
| fchan, err := fileutil.ReadFileWithReader(os.Stdin) | ||
| if err != nil { | ||
| return | ||
| } | ||
| for item := range fchan { | ||
| for item, err := range fileutil.LinesReader(os.Stdin) { | ||
| if err != nil { | ||
| return | ||
| } | ||
| if r.options.SkipDedupe || r.testAndSet(item) { | ||
| if !trySend(item) { | ||
| return | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: projectdiscovery/httpx
Length of output: 1521
🏁 Script executed:
Repository: projectdiscovery/httpx
Length of output: 1329
🏁 Script executed:
Repository: projectdiscovery/httpx
Length of output: 526
🏁 Script executed:
# Verify MySQL error code 1060 web_searchRepository: projectdiscovery/httpx
Length of output: 117
🌐 Web query:
MySQL error code 1060 duplicate column💡 Result:
MySQL error code 1060 (ER_DUP_FIELDNAME, SQLSTATE 42S21) occurs with the message "Duplicate column name '%s'".[1][2][3] It is triggered when attempting to define a column with a name that already exists in the table or result set, enforcing unique column names within tables and query results.[4][5][1] Common scenarios: - CREATE TABLE with duplicate column definitions, e.g., two 'email' columns.[4] - ALTER TABLE ADD COLUMN where the column already exists.[6] - SELECT * from joined tables with matching column names (e.g., both have 'id').[7] - CREATE VIEW without unique column aliases.[8] - Subqueries or INSERT...SELECT without column aliases.[9][10] Fixes: 1. Check the error message for the specific duplicate column name '%s'. 2. For CREATE/ALTER: Remove or rename the duplicate (e.g., ADD COLUMN
new_email).[4][6] 3. For SELECT/JOIN/VIEW: Use aliases, e.g., SELECT t1.id AS t1_id, t2.id AS t2_id.[7][8] Example: SELECT t.id AS tips_id FROM tips t LEFT JOIN tip_usage ON tip_usage.tip_id = t.id GROUP BY t.id;[7] 4. Verify table schema with SHOW CREATE TABLE or DESCRIBE table to confirm existing columns.[6] This behavior is consistent across MySQL versions including 8.0+ and 9.x, and also in MariaDB.[3][1][2]Citations:
🏁 Script executed:
Repository: projectdiscovery/httpx
Length of output: 75
🏁 Script executed:
Repository: projectdiscovery/httpx
Length of output: 48
🏁 Script executed:
# Check the actual go-sql-driver/mysql module to understand the error type web_searchRepository: projectdiscovery/httpx
Length of output: 117
🌐 Web query:
go-sql-driver mysql MySQLError type documentation💡 Result:
In github.com/go-sql-driver/mysql, MySQL server errors are represented by the struct type MySQLError (pointer receiver form is used): - Type: type MySQLError struct { Number uint16; SQLState [1]byte; Message string } [2] - String formatting: func (me *MySQLError) Error string {... } [2] - Error matching: func (me *MySQLError) Is(err error) bool { if merr, ok:= err.(*MySQLError); ok { return merr.Number == me.Number } return false } [2] So, for documentation/usage you typically: 1) Import the driver and run queries via database/sql. [3] 2) Type-assert / extract *mysql.MySQLError from returned errors when you want the MySQL error number and SQLState; the driver supports matching on MySQLError, including via errors.Is-style number matching because MySQLError defines Is. [2][4] Example (extract typed MySQL error): var mysqlErr *mysql.MySQLError if errors.As(err, &mysqlErr) { log.Printf("MySQL Error %d (%s): %s", mysqlErr.Number, string(mysqlErr.SQLState[:]), mysqlErr.Message) } This works because MySQLError carries Number/SQLState/Message. [2] Notes on exported sentinel errors: - The driver also defines various exported error variables (e.g., ErrInvalidConn, ErrMalformPkt, ErrNoTLS, etc.) for non–server-returned error scenarios, and these can be checked directly. [2] If you want the exact code definition, see errors.go in the driver repository. [2]
Citations:
Make the column migration safe for concurrent upgrades.
The
COUNT(*)+ALTER TABLEsequence at lines 181-199 is racy. If two instances start against the same pre-existing table, both can observe the column missing; oneADD COLUMNsucceeds and the other fails with MySQL error 1060 (duplicate column), so the migration is not idempotent during rolling deploys.💡 Suggested fix
🤖 Prompt for AI Agents