From 6689e73b90650e3f48d9050f7ae14a7822aec8c1 Mon Sep 17 00:00:00 2001 From: Chris Elder Date: Mon, 19 Feb 2018 14:14:42 -0500 Subject: [PATCH] [FAB-7886] Exclude non .json ext in deploy metadata When using Golang CC, the presence of a *.txt file (containing multiple json indexes) does not cause any issues in creating indexes from valid index definition files, but while using Node CC, the peer crashes with an error. Add a check in the ValidateMetadataFile to verify the file extension is ".json". Add a return value to indicate if the file should be included since returning an error would cause the peer to crash. Change-Id: Iceeca2d6683490eda9330becbe95a8a4ecedb5c0 Signed-off-by: Chris Elder --- core/common/ccprovider/metadata/validators.go | 39 +++++++++++++++---- .../ccprovider/metadata/validators_test.go | 29 ++++++++++++-- 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/core/common/ccprovider/metadata/validators.go b/core/common/ccprovider/metadata/validators.go index 06dea70385b..92cc684fe51 100644 --- a/core/common/ccprovider/metadata/validators.go +++ b/core/common/ccprovider/metadata/validators.go @@ -8,9 +8,9 @@ package metadata import ( "encoding/json" - "errors" "fmt" "io/ioutil" + "path/filepath" "reflect" "strings" @@ -36,18 +36,28 @@ func (e *UnhandledDirectoryError) Error() string { return e.err } -// InvalidFileError is returned for invalid metadata files -type InvalidFileError struct { +// BadExtensionError is returned for metadata files with extension other than .json +type BadExtensionError struct { err string } -func (e *InvalidFileError) Error() string { +func (e *BadExtensionError) Error() string { + return e.err +} + +// InvalidIndexContentError is returned for metadata files with invalid content +type InvalidIndexContentError struct { + err string +} + +func (e *InvalidIndexContentError) Error() string { return e.err } // ValidateMetadataFile checks that metadata files are valid // according to the validation rules of the metadata directory (metadataType) func ValidateMetadataFile(srcPath, metadataType string) error { + // Get the validator handler for the metadata directory fileValidator, ok := fileValidators[metadataType] @@ -56,10 +66,10 @@ func ValidateMetadataFile(srcPath, metadataType string) error { return &UnhandledDirectoryError{fmt.Sprintf("Metadata not supported in directory: %s", metadataType)} } - // If the file is not valid for the given metadata directory, return InvalidFileError + // If the file is not valid for the given metadata directory, return an error err := fileValidator(srcPath) if err != nil { - return &InvalidFileError{fmt.Sprintf("Metadata file [%s] failed validation: %s", srcPath, err)} + return err } // file is valid, return nil error @@ -68,6 +78,14 @@ func ValidateMetadataFile(srcPath, metadataType string) error { // couchdbIndexFileValidator implements fileValidator func couchdbIndexFileValidator(srcPath string) error { + + ext := filepath.Ext(srcPath) + + // if the file does not have a .json extension, then return as error + if ext != ".json" { + return &BadExtensionError{fmt.Sprintf("Index metadata file [%s] does not have a .json extension", srcPath)} + } + fileBytes, err := ioutil.ReadFile(srcPath) if err != nil { return err @@ -76,11 +94,16 @@ func couchdbIndexFileValidator(srcPath string) error { // if the content does not validate as JSON, return err to invalidate the file boolIsJSON, indexDefinition := isJSON(fileBytes) if !boolIsJSON { - return errors.New("File is not valid JSON") + return &InvalidIndexContentError{fmt.Sprintf("Index metadata file [%s] is not a valid JSON", srcPath)} } // validate the index definition - return validateIndexJSON(indexDefinition) + err = validateIndexJSON(indexDefinition) + if err != nil { + return &InvalidIndexContentError{fmt.Sprintf("Index metadata file [%s] is not a valid index definition: %s", srcPath, err)} + } + + return nil } diff --git a/core/common/ccprovider/metadata/validators_test.go b/core/common/ccprovider/metadata/validators_test.go index f38fe8f92fa..fcf4b08f287 100644 --- a/core/common/ccprovider/metadata/validators_test.go +++ b/core/common/ccprovider/metadata/validators_test.go @@ -45,11 +45,11 @@ func TestBadIndexJSON(t *testing.T) { err = ValidateMetadataFile(filename, "META-INF/statedb/couchdb/indexes") - assert.Error(t, err, "Should have received an InvalidFileError") + assert.Error(t, err, "Should have received an InvalidIndexContentError") - // Type assertion on InvalidFileError - _, ok := err.(*InvalidFileError) - assert.True(t, ok, "Should have received an InvalidFileError") + // Type assertion on InvalidIndexContentError + _, ok := err.(*InvalidIndexContentError) + assert.True(t, ok, "Should have received an InvalidIndexContentError") t.Log("SAMPLE ERROR STRING:", err.Error()) } @@ -108,6 +108,27 @@ func TestCantReadFile(t *testing.T) { err := ValidateMetadataFile(filename, "META-INF/statedb/couchdb/indexes") assert.Error(t, err, "Should have received error reading file") + +} + +func TestBadMetadataExtension(t *testing.T) { + testDir := filepath.Join(packageTestDir, "BadMetadataExtension") + cleanupDir(testDir) + defer cleanupDir(testDir) + + filename := filepath.Join(testDir, "META-INF/statedb/couchdb/indexes", "myIndex.go") + filebytes := []byte(`{"index":{"fields":["data.docType","data.owner"]},"name":"indexOwner","type":"json"}`) + + err := writeToFile(filename, filebytes) + assert.NoError(t, err, "Error writing to file") + + err = ValidateMetadataFile(filename, "META-INF/statedb/couchdb/indexes") + assert.Error(t, err, "Should have received an BadExtensionError") + + // Type assertion on BadExtensionError + _, ok := err.(*BadExtensionError) + assert.True(t, ok, "Should have received an BadExtensionError") + } func TestIndexValidation(t *testing.T) {