Skip to content

Commit 0dc2fbe

Browse files
authored
Add string check and isNil Panic protection (#34)
1 parent 2e95db9 commit 0dc2fbe

File tree

2 files changed

+76
-12
lines changed

2 files changed

+76
-12
lines changed

remoteconfig.go

+20-3
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@ func ReadJSONValidate(cfgReader io.Reader, configStruct interface{}) error {
5151
return nil
5252
}
5353

54+
func isNilFixed(v reflect.Value) bool {
55+
switch v.Kind() {
56+
case reflect.Ptr, reflect.Map, reflect.Array, reflect.Chan, reflect.Slice:
57+
//use of IsNil method
58+
return v.IsNil()
59+
}
60+
return false
61+
}
62+
5463
// Validates a configuration struct.
5564
// Uses reflection to determine and call the correct Validation methods for each type.
5665
func validateConfigWithReflection(c interface{}) error {
@@ -78,9 +87,9 @@ func validateConfigWithReflection(c interface{}) error {
7887
continue
7988
}
8089

81-
if valueField.IsNil() && !optional {
90+
if isNilFixed(valueField) && !optional {
8291
return fmt.Errorf("Field: %s, not set", typeField.Name)
83-
} else if valueField.IsNil() && optional {
92+
} else if isNilFixed(valueField) && optional {
8493
continue
8594
}
8695

@@ -115,14 +124,22 @@ func validateConfigWithReflection(c interface{}) error {
115124
continue
116125
}
117126

118-
// If this is a string field, check that it isn't empty (unless optional)
127+
// If this is a string pointer field, check that it isn't empty (unless optional)
119128
if s, ok := valueField.Interface().(*string); ok {
120129
if *s == "" {
121130
return fmt.Errorf("String Field: %s, contains an empty string", typeField.Name)
122131
}
123132
continue
124133
}
125134

135+
// If this is a string field, check that it isn't empty (unless optional)
136+
if s, ok := valueField.Interface().(string); ok {
137+
if s == "" {
138+
return fmt.Errorf("String Field: %s, contains an empty string", typeField.Name)
139+
}
140+
continue
141+
}
142+
126143
// If the Validater interface is implemented, call the Validate method
127144
if typeField.Type.Implements(validaterType) {
128145
if err := valueField.Interface().(Validater).Validate(); err != nil {

remoteconfig_test.go

+56-9
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ type SampleConfig struct {
5050
SQSClient *SQSClientConfig `json:"sqs_client,omitempty"`
5151
DynamoDBTable *DynamoDBTableConfig `json:"dynamodb_table,omitempty"`
5252
DynamoDBClient *DynamoDBClientConfig `json:"dynamodb_client,omitempty"`
53-
Str *string `json:"str,omitempty"`
53+
Str string `json:"str,omitempty"`
54+
StrPointer *string `json:"str_pointer,omitempty"`
5455
StorageConfig *StorageConfig `json:"storage_config,omitempty"`
5556
StorageConfigSlice []*StorageConfig `json:"storage_config_slice,omitempty"`
5657
StorageConfigMap map[string]*StorageConfig `json:"storage_config_map,omitempty"`
@@ -79,6 +80,7 @@ var validConfigJSON = `
7980
"table_name" : "testTable"
8081
},
8182
"str" : "testStr",
83+
"str_pointer" : "testStr",
8284
"storage_config" : {
8385
"provider" : "aws",
8486
"location" : "us-west-2"
@@ -151,7 +153,8 @@ func (s *RemoteConfigSuite) TestValidateConfigWithReflectionWithOptional() {
151153
SQSClient: sqsClient,
152154
DynamoDBTable: dynamodbTable,
153155
DynamoDBClient: dynamodbClient,
154-
Str: &str,
156+
Str: str,
157+
StrPointer: &str,
155158
StorageConfig: storageConfig,
156159
StorageConfigSlice: []*StorageConfig{storageConfig},
157160
StorageConfigMap: map[string]*StorageConfig{"one": storageConfig},
@@ -348,12 +351,52 @@ func (s *RemoteConfigSuite) TestValidateConfigWithReflectionErrorStrNotSet() {
348351
SQSClient: sqsClient,
349352
DynamoDBTable: dynamodbTable,
350353
DynamoDBClient: dynamodbClient,
351-
Str: nil,
354+
Str: "testString",
355+
StrPointer: nil,
352356
}
353357

354358
err := validateConfigWithReflection(c)
355359
assert.NotNil(s.T(), err)
356-
assert.Equal(s.T(), errors.New("Field: Str, not set"), err)
360+
assert.Equal(s.T(), errors.New("Field: StrPointer, not set"), err)
361+
}
362+
363+
func (s *RemoteConfigSuite) TestValidateConfigWithReflectionErrorStrPointerEmpty() {
364+
sqsRegion := VALID_REMOTE_CONFIG_SQS_REGION
365+
sqsAWSAccountID := VALID_REMOTE_CONFIG_SQS_AWS_ACCOUNT_ID
366+
sqsQueueName := VALID_REMOTE_CONFIG_SQS_QUEUE_NAME
367+
sqsQueue := &SQSQueueConfig{
368+
Region: &sqsRegion,
369+
AWSAccountID: &sqsAWSAccountID,
370+
QueueName: &sqsQueueName,
371+
}
372+
sqsClient := &SQSClientConfig{
373+
Region: &sqsRegion,
374+
}
375+
376+
dynamodbTableName := VALID_REMOTE_CONFIG_DYNAMODB_TABLE_NAME
377+
dynamodbTable := &DynamoDBTableConfig{
378+
TableName: &dynamodbTableName,
379+
}
380+
381+
dynamodbClientRegion := VALID_REMOTE_CONFIG_DYNAMODB_CLIENT_REGION
382+
dynamodbClient := &DynamoDBClientConfig{
383+
Region: &dynamodbClientRegion,
384+
}
385+
386+
str := ""
387+
388+
c := &SampleConfig{
389+
SQSQueue: sqsQueue,
390+
SQSClient: sqsClient,
391+
DynamoDBTable: dynamodbTable,
392+
DynamoDBClient: dynamodbClient,
393+
Str: "testString",
394+
StrPointer: &str,
395+
}
396+
397+
err := validateConfigWithReflection(c)
398+
assert.NotNil(s.T(), err)
399+
assert.Equal(s.T(), errors.New("String Field: StrPointer, contains an empty string"), err)
357400
}
358401

359402
func (s *RemoteConfigSuite) TestValidateConfigWithReflectionErrorStrEmpty() {
@@ -386,7 +429,7 @@ func (s *RemoteConfigSuite) TestValidateConfigWithReflectionErrorStrEmpty() {
386429
SQSClient: sqsClient,
387430
DynamoDBTable: dynamodbTable,
388431
DynamoDBClient: dynamodbClient,
389-
Str: &str,
432+
Str: str,
390433
}
391434

392435
err := validateConfigWithReflection(c)
@@ -424,7 +467,8 @@ func (s *RemoteConfigSuite) TestValidateConfigWithReflectionErrorStorageConfigNo
424467
SQSClient: sqsClient,
425468
DynamoDBTable: dynamodbTable,
426469
DynamoDBClient: dynamodbClient,
427-
Str: &str,
470+
Str: str,
471+
StrPointer: &str,
428472
StorageConfig: nil,
429473
}
430474

@@ -470,7 +514,8 @@ func (s *RemoteConfigSuite) TestValidateConfigWithReflectionErrorStorageConfigSl
470514
SQSClient: sqsClient,
471515
DynamoDBTable: dynamodbTable,
472516
DynamoDBClient: dynamodbClient,
473-
Str: &str,
517+
Str: str,
518+
StrPointer: &str,
474519
StorageConfig: storageConfig,
475520
StorageConfigSlice: nil,
476521
}
@@ -549,7 +594,8 @@ func (s *RemoteConfigSuite) TestValidateConfigWithReflectionErrorStorageConfigSl
549594
SQSClient: sqsClient,
550595
DynamoDBTable: dynamodbTable,
551596
DynamoDBClient: dynamodbClient,
552-
Str: &str,
597+
Str: str,
598+
StrPointer: &str,
553599
StorageConfig: storageConfig,
554600
StorageConfigSlice: []*StorageConfig{},
555601
}
@@ -691,7 +737,8 @@ func (s *RemoteConfigSuite) buildValidSampleConfig() *SampleConfig {
691737
SQSClient: sqsClient,
692738
DynamoDBTable: dynamodbTable,
693739
DynamoDBClient: dynamodbClient,
694-
Str: &str,
740+
Str: str,
741+
StrPointer: &str,
695742
StorageConfig: storageConfig,
696743
StorageConfigSlice: []*StorageConfig{storageConfig},
697744
StorageConfigMap: map[string]*StorageConfig{"one": storageConfig},

0 commit comments

Comments
 (0)