Skip to content
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

Update documentation and Go report #12

Merged
merged 5 commits into from
Feb 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 44 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,50 @@
## SQLfuzz

[![Go Report Card](https://goreportcard.com/badge/github.com/PumpkinSeed/sqlfuzz)](https://goreportcard.com/report/github.com/PumpkinSeed/sqlfuzz) [![GoDoc](https://godoc.org/github.com/PumpkinSeed/sqlfuzz?status.svg)](https://godoc.org/github.com/PumpkinSeed/sqlfuzz) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![made-with-Go](https://img.shields.io/badge/Made%20with-Go-1f425f.svg)](http://golang.org) ![sqlfuzz test workflow](https://github.com/PumpkinSeed/sqlfuzz/actions/workflows/test.yml/badge.svg)

Load random data into SQL tables for testing purposes. The tool can get the layout of the SQL table and fill it up with random data.

#### Usage
- [Installation](#installation)
- [Usage](#usage)
- [Flags](#flags)
- [Package usage](#package-usage)

### Installation

#### MacOS

```
go install github.com/PumpkinSeed/sqlfuzz
wget https://github.com/PumpkinSeed/sqlfuzz/releases/download/{RELEASE}/sqlfuzz_darwin_amd64 -O /usr/local/bin/sqlfuzz
chmod +x /usr/local/bin/sqlfuzz
```

#### Linux

```
# amd64 build
wget https://github.com/PumpkinSeed/sqlfuzz/releases/download/{RELEASE}/sqlfuzz_linux_amd64 -O /usr/local/bin/sqlfuzz
chmod +x /usr/local/bin/sqlfuzz

# arm64 build
wget https://github.com/PumpkinSeed/sqlfuzz/releases/download/{RELEASE}/sqlfuzz_linux_arm64 -O /usr/local/bin/sqlfuzz
chmod +x /usr/local/bin/sqlfuzz
```

#### Windows

You can download the Windows build [here](https://github.com/PumpkinSeed/sqlfuzz/releases/download/v0.3.0/sqlfuzz_windows_amd64.exe)

#### Build from source

```
wget https://github.com/PumpkinSeed/sqlfuzz/archive/{RELEASE}.zip
# unzip
# cd into dir
go install main.go
```

### Usage

```
sqlfuzz -u username -p password -d database -h 127.0.0.1 -t table -n 100000 -w 100
```
Expand All @@ -22,4 +59,8 @@ sqlfuzz -u username -p password -d database -h 127.0.0.1 -t table -n 100000 -w 1
- `D`: Driver for database connection (currently only `mysql`)
- `t`: Table for fuzzing
- `n`: Number of rows to fuzz
- `w`: Concurrent workers to work on fuzzing
- `w`: Concurrent workers to work on fuzzing

### Package usage

TODO: Write package
16 changes: 10 additions & 6 deletions drivers/entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,32 +19,36 @@ const (
Unknown
)

// Flags needed by the driver
type Flags struct {
Username string
Password string
Database string
Host string
Port string
Driver string
Host string
Port string
Driver string
}

// Field is the possible field definition
type Field struct {
Type Type
Type Type
Length int16
Enum []string
Enum []string
}

// Driver is the interface should satisfied by a certain driver
type Driver interface {
Connection() string
Driver() string
Insert(fields []string, table string) string
MapField(string) Field
}

// New creates a new driver instance based on the flags
func New(f Flags) Driver {
switch f.Driver {
case "mysql":
return MySQL{f:f}
return MySQL{f: f}
default:
log.Fatal("Driver not implemented")
return nil
Expand Down
15 changes: 6 additions & 9 deletions drivers/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,10 @@ func length(field string, t string) []int16 {
result = append(result, int16(data))
}
return result
} else {
v, err := strconv.Atoi(str)
if err != nil {
panic(err)
}
return []int16{int16(v)}
}

return nil
}
v, err := strconv.Atoi(str)
if err != nil {
panic(err)
}
return []int16{int16(v)}
}
7 changes: 6 additions & 1 deletion drivers/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,28 @@ import (
"strings"
)

// MySQL implementation of the Driver
type MySQL struct {
f Flags
}

// Connection returns the specific connection string
func (m MySQL) Connection() string {
return fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", m.f.Username, m.f.Password, m.f.Host, m.f.Port, m.f.Database)
}

// Driver returns the name of the driver
func (m MySQL) Driver() string {
return m.f.Driver
}

// Insert inserts the data into
func (m MySQL) Insert(fields []string, table string) string {
var template = "INSERT INTO %s(`%s`) VALUES(%s)"
return fmt.Sprintf(template, table, strings.Join(fields, "`,`"), questionMarks(len(fields)))
}

// MapField returns the actual fields
func (m MySQL) MapField(field string) Field {
field = strings.ToLower(field)
// String types
Expand Down Expand Up @@ -64,7 +69,7 @@ func (m MySQL) MapField(field string) Field {
if strings.HasPrefix(field, "mediumint") {
return Field{Type: Int16, Length: -1}
}
if strings.HasPrefix(field, "int") || strings.HasPrefix(field, "bigint"){
if strings.HasPrefix(field, "int") || strings.HasPrefix(field, "bigint") {
return Field{Type: Int32, Length: -1}
}

Expand Down
48 changes: 24 additions & 24 deletions drivers/mysql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,95 +7,95 @@ import (

func TestMapField(t *testing.T) {
var scenarios = []struct {
input string
input string
output Field
}{
{
input:"varchar(12)",
input: "varchar(12)",
output: Field{Type: String, Length: 12},
},
{
input:"char(100)",
input: "char(100)",
output: Field{Type: String, Length: 100},
},
{
input:"varbinary(100)",
input: "varbinary(100)",
output: Field{Type: String, Length: 100},
},
{
input:"binary(100)",
input: "binary(100)",
output: Field{Type: String, Length: 100},
},
{
input:"tinyint",
input: "tinyint",
output: Field{Type: Bool, Length: -1},
},
{
input:"smallint",
input: "smallint",
output: Field{Type: Int16, Length: -1},
},
{
input:"mediumint",
input: "mediumint",
output: Field{Type: Int16, Length: -1},
},
{
input:"int",
input: "int",
output: Field{Type: Int32, Length: -1},
},
{
input:"bigint",
input: "bigint",
output: Field{Type: Int32, Length: -1},
},
{
input:"decimal(12, 4)",
input: "decimal(12, 4)",
output: Field{Type: Float, Length: 8},
},
{
input:"float(12, 5)",
input: "float(12, 5)",
output: Field{Type: Float, Length: 7},
},
{
input:"double(20,5)",
input: "double(20,5)",
output: Field{Type: Float, Length: 15},
},
{
input:"blob",
input: "blob",
output: Field{Type: Blob, Length: -1},
},
{
input:"tinyblob",
input: "tinyblob",
output: Field{Type: Blob, Length: -1},
},
{
input:"mediumblob",
input: "mediumblob",
output: Field{Type: Blob, Length: -1},
},
{
input:"longblob",
input: "longblob",
output: Field{Type: Blob, Length: -1},
},
{
input:"text",
input: "text",
output: Field{Type: Text, Length: -1},
},
{
input:"tinytext",
input: "tinytext",
output: Field{Type: Text, Length: -1},
},
{
input:"mediumtext",
input: "mediumtext",
output: Field{Type: Text, Length: -1},
},
{
input:"longtext",
input: "longtext",
output: Field{Type: Text, Length: -1},
},
{
input:"json",
input: "json",
output: Field{Type: Json, Length: -1},
},
{
input:"enum(test, this, data)",
input: "enum(test, this, data)",
output: Field{Type: Enum, Length: -1, Enum: []string{"test", "this", "data"}},
},
}
Expand All @@ -107,4 +107,4 @@ func TestMapField(t *testing.T) {
t.Errorf("Invalid output for %s, out: %+v", scenario.input, output)
}
}
}
}
6 changes: 3 additions & 3 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ func TestFuzz(t *testing.T) {
Username: "mysql",
Password: "mysql",
Database: "mysql",
Host: "127.0.0.1",
Port: "3306",
Driver:"mysql",
Host: "127.0.0.1",
Port: "3306",
Driver: "mysql",
}
f.Table = "Persons"
f.Parsed = true
Expand Down
1 change: 1 addition & 0 deletions pkg/descriptor/tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"database/sql"
)

// ShowTables queries the available tables of the database
func ShowTables(db *sql.DB) ([]string, error) {
results, err := db.Query("SHOW TABLES;")
if err != nil {
Expand Down