From 1d396c94d511a94b3aae6d55236408b9a18de98d Mon Sep 17 00:00:00 2001 From: glorv Date: Thu, 12 Nov 2020 16:34:05 +0800 Subject: [PATCH] mydumper: verify file routing config (#470) * fix file routing * remove useless line * remove redundant if check --- lightning/config/config.go | 15 +++++++++++++++ lightning/config/config_test.go | 19 +++++++++++++++++++ lightning/mydump/router.go | 3 +++ lightning/mydump/router_test.go | 31 +++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+) diff --git a/lightning/config/config.go b/lightning/config/config.go index 1dc03052c2a95..29337750aed75 100644 --- a/lightning/config/config.go +++ b/lightning/config/config.go @@ -479,6 +479,21 @@ func (cfg *Config) Adjust() error { } } + // adjust file routing + for _, rule := range cfg.Mydumper.FileRouters { + if filepath.IsAbs(rule.Path) { + relPath, err := filepath.Rel(cfg.Mydumper.SourceDir, rule.Path) + if err != nil { + return errors.Trace(err) + } + // ".." means that this path is not in source dir, so we should return an error + if strings.HasPrefix(relPath, "..") { + return errors.Errorf("file route path '%s' is not in source dir '%s'", rule.Path, cfg.Mydumper.SourceDir) + } + rule.Path = relPath + } + } + // enable default file route rule if no rules are set if len(cfg.Mydumper.FileRouters) == 0 { cfg.Mydumper.DefaultFileRules = true diff --git a/lightning/config/config_test.go b/lightning/config/config_test.go index 8cf67cd21bf35..a848daf73e09a 100644 --- a/lightning/config/config_test.go +++ b/lightning/config/config_test.go @@ -132,6 +132,25 @@ func (s *configTestSuite) TestAdjustInvalidBackend(c *C) { c.Assert(err, ErrorMatches, "invalid config: unsupported `tikv-importer\\.backend` \\(no_such_backend\\)") } +func (s *configTestSuite) TestAdjustFileRoutePath(c *C) { + cfg := config.NewConfig() + assignMinimalLegalValue(cfg) + + tmpDir := c.MkDir() + cfg.Mydumper.SourceDir = tmpDir + invalidPath := filepath.Join(tmpDir, "../test123/1.sql") + rule := &config.FileRouteRule{Path: invalidPath, Type: "sql", Schema: "test", Table: "tbl"} + cfg.Mydumper.FileRouters = []*config.FileRouteRule{rule} + err := cfg.Adjust() + c.Assert(err, ErrorMatches, fmt.Sprintf("file route path '%s' is not in source dir '%s'", invalidPath, tmpDir)) + + relPath := "test_dir/1.sql" + rule.Path = filepath.Join(tmpDir, relPath) + err = cfg.Adjust() + c.Assert(err, IsNil) + c.Assert(cfg.Mydumper.FileRouters[0].Path, Equals, relPath) +} + func (s *configTestSuite) TestDecodeError(c *C) { ts, host, port := startMockServer(c, http.StatusOK, "invalid-string") defer ts.Close() diff --git a/lightning/mydump/router.go b/lightning/mydump/router.go index 93e5b9240999a..74c687bfad53f 100644 --- a/lightning/mydump/router.go +++ b/lightning/mydump/router.go @@ -176,6 +176,9 @@ type regexRouterParser struct{} func (p regexRouterParser) Parse(r *config.FileRouteRule) (*RegexRouter, error) { rule := &RegexRouter{} + if r.Path == "" && r.Pattern == "" { + return nil, errors.New("`path` and `pattern` must not be both empty in [[mydumper.files]]") + } if r.Path != "" && r.Pattern != "" { return nil, errors.New("can't set both `path` and `pattern` field in [[mydumper.files]]") } diff --git a/lightning/mydump/router_test.go b/lightning/mydump/router_test.go index 3be8e6e66fe43..9b06e2fb0ddb8 100644 --- a/lightning/mydump/router_test.go +++ b/lightning/mydump/router_test.go @@ -40,6 +40,37 @@ func (t *testFileRouterSuite) TestRouteParser(c *C) { } } +func (t *testFileRouterSuite) TestInvalidRouteRule(c *C) { + rule := &config.FileRouteRule{} + rules := []*config.FileRouteRule{rule} + _, err := NewFileRouter(rules) + c.Assert(err, ErrorMatches, "`path` and `pattern` must not be both empty in \\[\\[mydumper.files\\]\\]") + + rule.Pattern = `^(?:[^/]*/)*([^/.]+)\.(?P[^./]+)(?:\.(?P[0-9]+))?\.(?Pcsv|sql)(?:\.(?P[A-Za-z0-9]+))?$` + _, err = NewFileRouter(rules) + c.Assert(err, ErrorMatches, "field 'type' match pattern can't be empty") + + rule.Type = "$type" + _, err = NewFileRouter(rules) + c.Assert(err, ErrorMatches, "field 'schema' match pattern can't be empty") + + rule.Schema = "$schema" + _, err = NewFileRouter(rules) + c.Assert(err, ErrorMatches, "invalid named capture '\\$schema'") + + rule.Schema = "$1" + _, err = NewFileRouter(rules) + c.Assert(err, ErrorMatches, "field 'table' match pattern can't be empty") + + rule.Table = "$table" + _, err = NewFileRouter(rules) + c.Assert(err, IsNil) + + rule.Path = "/tmp/1.sql" + _, err = NewFileRouter(rules) + c.Assert(err, ErrorMatches, "can't set both `path` and `pattern` field in \\[\\[mydumper.files\\]\\]") +} + func (t *testFileRouterSuite) TestSingleRouteRule(c *C) { rules := []*config.FileRouteRule{ {Pattern: `^(?:[^/]*/)*([^/.]+)\.(?P
[^./]+)(?:\.(?P[0-9]+))?\.(?Pcsv|sql)(?:\.(?P[A-Za-z0-9]+))?$`, Schema: "$1", Table: "$table", Type: "$type", Key: "$key", Compression: "$cp"},