Skip to content

Commit

Permalink
Validate database names for SQLite handler (#2924)
Browse files Browse the repository at this point in the history
  • Loading branch information
noisersup committed Jun 30, 2023
1 parent e78942e commit 11a2389
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 12 deletions.
68 changes: 59 additions & 9 deletions integration/basic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,46 @@ func TestDatabaseName(t *testing.T) {

t.Parallel()

t.Run("NoErr", func(t *testing.T) {
ctx, collection := setup.Setup(t)
for name, tc := range map[string]struct {
db string // database name, defaults to empty string
skip string // optional, skip test with a specified reason
}{
"Dash": {
db: "--",
},
"Underscore": {
db: "__",
},
"Sqlite": {
db: "sqlite_",
},
"Number": {
db: "0prefix",
},
"63ok": {
db: strings.Repeat("a", 63),
},
} {
name, tc := name, tc
t.Run(name, func(t *testing.T) {
if tc.skip != "" {
t.Skip(tc.skip)
}

t.Parallel()

// there is no explicit command to create database, so create collection instead
err := collection.Database().Client().Database(tc.db).CreateCollection(ctx, collection.Name())
require.NoError(t, err)

err = collection.Database().Client().Database(tc.db).Drop(ctx)
require.NoError(t, err)
})
}
})

t.Run("Err", func(t *testing.T) {
ctx, collection := setup.Setup(t)

Expand All @@ -471,6 +511,25 @@ func TestDatabaseName(t *testing.T) {
},
altMessage: fmt.Sprintf("Invalid namespace: %s.%s", dbName64, "TestDatabaseName-Err"),
},
"WithASlash": {
db: "/",
err: &mongo.CommandError{
Name: "InvalidNamespace",
Code: 73,
Message: `Invalid namespace specified '/.TestDatabaseName-Err'`,
},
altMessage: `Invalid namespace: /.TestDatabaseName-Err`,
},

"WithABackslash": {
db: "\\",
err: &mongo.CommandError{
Name: "InvalidNamespace",
Code: 73,
Message: `Invalid namespace specified '\.TestDatabaseName-Err'`,
},
altMessage: `Invalid namespace: \.TestDatabaseName-Err`,
},
"WithADollarSign": {
db: "name_with_a-$",
err: &mongo.CommandError{
Expand Down Expand Up @@ -516,15 +575,6 @@ func TestDatabaseName(t *testing.T) {
})
}
})

t.Run("63ok", func(t *testing.T) {
ctx, collection := setup.Setup(t)

dbName63 := strings.Repeat("a", 63)
err := collection.Database().Client().Database(dbName63).CreateCollection(ctx, collection.Name())
require.NoError(t, err)
collection.Database().Client().Database(dbName63).Drop(ctx)
})
}

func TestDebugError(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion internal/handlers/pg/pgdb/databases.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
)

// validateDatabaseNameRe validates FerretDB database / PostgreSQL schema names.
var validateDatabaseNameRe = regexp.MustCompile("^[a-zA-Z_-][a-zA-Z0-9_-]{0,62}$")
var validateDatabaseNameRe = regexp.MustCompile("^[a-zA-Z0-9_-]{1,63}$")

// Databases returns a sorted list of FerretDB databases / PostgreSQL schemas.
func Databases(ctx context.Context, tx pgx.Tx) ([]string, error) {
Expand Down
13 changes: 11 additions & 2 deletions internal/handlers/sqlite/msg_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package sqlite
import (
"context"
"fmt"
"regexp"

"github.com/FerretDB/FerretDB/internal/backends"
"github.com/FerretDB/FerretDB/internal/handlers/common"
Expand All @@ -27,6 +28,9 @@ import (
"github.com/FerretDB/FerretDB/internal/wire"
)

// validateDatabaseNameRe validates FerretDB database name.
var validateDatabaseNameRe = regexp.MustCompile("^[a-zA-Z0-9_-]{1,63}$")

// MsgCreate implements HandlerInterface.
func (h *Handler) MsgCreate(ctx context.Context, msg *wire.OpMsg) (*wire.OpMsg, error) {
document, err := msg.Document()
Expand Down Expand Up @@ -78,6 +82,11 @@ func (h *Handler) MsgCreate(ctx context.Context, msg *wire.OpMsg) (*wire.OpMsg,
return nil, err
}

if !validateDatabaseNameRe.MatchString(dbName) {
msg := fmt.Sprintf("Invalid namespace: %s.%s", dbName, collectionName)
return nil, commonerrors.NewCommandErrorMsgWithArgument(commonerrors.ErrInvalidNamespace, msg, "create")
}

db := h.b.Database(dbName)
defer db.Close()

Expand All @@ -98,11 +107,11 @@ func (h *Handler) MsgCreate(ctx context.Context, msg *wire.OpMsg) (*wire.OpMsg,

case backends.ErrorCodeIs(err, backends.ErrorCodeCollectionAlreadyExists):
msg := fmt.Sprintf("Collection %s.%s already exists.", dbName, collectionName)
return nil, commonerrors.NewCommandErrorMsg(commonerrors.ErrNamespaceExists, msg)
return nil, commonerrors.NewCommandErrorMsgWithArgument(commonerrors.ErrNamespaceExists, msg, "create")

case backends.ErrorCodeIs(err, backends.ErrorCodeCollectionNameIsInvalid):
msg := fmt.Sprintf("Invalid namespace: %s.%s", dbName, collectionName)
return nil, commonerrors.NewCommandErrorMsg(commonerrors.ErrInvalidNamespace, msg)
return nil, commonerrors.NewCommandErrorMsgWithArgument(commonerrors.ErrInvalidNamespace, msg, "create")

default:
return nil, lazyerrors.Error(err)
Expand Down

0 comments on commit 11a2389

Please sign in to comment.