Skip to content

Commit

Permalink
internal/ini: Fix ini parser to handle empty values (aws#2860)
Browse files Browse the repository at this point in the history
The ini parser incorrectly decided whether a statement should be skipped. As a result, valid statements in the ini files were being squashed. The PR fixes incorrect modifications to the previous token value of the skipper. We also add checks for cases where a skipped statement should be marked as complete and not be ignored.

Adds test cases for cases for statements that need to be skipped. Also adds suggested tests from aws#2801 . Fixes aws#2800
  • Loading branch information
skotambkar authored Oct 1, 2019
1 parent 5f1c1f9 commit 02207b1
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG_PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@
### SDK Enhancements

### SDK Bugs
* `internal/ini`: Fix ini parser to handle empty values [#2860](https://github.com/aws/aws-sdk-go/pull/2860)
* Fixes incorrect modifications to the previous token value of the skipper. Adds checks for cases where a skipped statement should be marked as complete and not be ignored.
* Adds tests for nested and empty field value parsing, along with tests suggested in [#2801](https://github.com/aws/aws-sdk-go/pull/2801)
* Fixes [#2800](https://github.com/aws/aws-sdk-go/issues/2800)
11 changes: 9 additions & 2 deletions internal/ini/ini_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ loop:
if len(tokens) == 0 {
break loop
}

// if should skip is true, we skip the tokens until should skip is set to false.
step = SkipTokenState
}

Expand Down Expand Up @@ -218,7 +218,7 @@ loop:
// S -> equal_expr' expr_stmt'
switch k.Kind {
case ASTKindEqualExpr:
// assiging a value to some key
// assigning a value to some key
k.AppendChild(newExpression(tok))
stack.Push(newExprStatement(k))
case ASTKindExpr:
Expand Down Expand Up @@ -250,6 +250,13 @@ loop:
if !runeCompare(tok.Raw(), openBrace) {
return nil, NewParseError("expected '['")
}
// If OpenScopeState is not at the start, we must mark the previous ast as complete
//
// for example: if previous ast was a skip statement;
// we should mark it as complete before we create a new statement
if k.Kind != ASTKindStart {
stack.MarkComplete(k)
}

stmt := newStatement()
stack.Push(stmt)
Expand Down
19 changes: 19 additions & 0 deletions internal/ini/ini_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,25 @@ region = us-west-2
newExprStatement(noQuotesRegionEQRegion),
},
},
{
name: "missing section statement",
r: bytes.NewBuffer([]byte(
`[default]
s3 =
[assumerole]
output = json
`)),
expectedStack: []AST{
newCompletedSectionStatement(
defaultProfileStmt,
),
newSkipStatement(newEqualExpr(newExpression(s3ID), equalOp)),
newCompletedSectionStatement(
assumeProfileStmt,
),
newExprStatement(outputEQExpr),
},
},
}

for i, c := range cases {
Expand Down
6 changes: 3 additions & 3 deletions internal/ini/skipper.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,24 @@ func newSkipper() skipper {
}

func (s *skipper) ShouldSkip(tok Token) bool {
// should skip state will be modified only if previous token was new line (NL);
// and the current token is not WhiteSpace (WS).
if s.shouldSkip &&
s.prevTok.Type() == TokenNL &&
tok.Type() != TokenWS {

s.Continue()
return false
}
s.prevTok = tok

return s.shouldSkip
}

func (s *skipper) Skip() {
s.shouldSkip = true
s.prevTok = emptyToken
}

func (s *skipper) Continue() {
s.shouldSkip = false
// empty token is assigned as we return to default state, when should skip is false
s.prevTok = emptyToken
}
12 changes: 12 additions & 0 deletions internal/ini/testdata/valid/issue_2800
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[foo]
aws_access_key_id =
aws_secret_access_key =
aws_session_token =
[bar]
aws_access_key_id = valid
aws_secret_access_key = valid
aws_session_token = valid
[baz]
aws_access_key_id = valid
aws_secret_access_key = valid
aws_session_token = valid
14 changes: 14 additions & 0 deletions internal/ini/testdata/valid/issue_2800_expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"foo": {
},
"bar": {
"aws_access_key_id": "valid",
"aws_secret_access_key": "valid",
"aws_session_token": "valid"
},
"baz": {
"aws_access_key_id": "valid",
"aws_secret_access_key": "valid",
"aws_session_token": "valid"
}
}
12 changes: 12 additions & 0 deletions internal/ini/testdata/valid/nested_fields
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[foo]
aws_access_key_id =
aws_secret_access_key = valid
aws_session_token = valid
[bar]
aws_access_key_id = valid
aws_secret_access_key = valid
aws_session_token = valid
[baz]
aws_access_key_id = valid
aws_secret_access_key = valid
aws_session_token = valid
15 changes: 15 additions & 0 deletions internal/ini/testdata/valid/nested_fields_expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"foo": {
"aws_session_token": "valid"
},
"bar": {
"aws_access_key_id": "valid",
"aws_secret_access_key": "valid",
"aws_session_token": "valid"
},
"baz": {
"aws_access_key_id": "valid",
"aws_secret_access_key": "valid",
"aws_session_token": "valid"
}
}
2 changes: 1 addition & 1 deletion internal/ini/walker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func TestValidDataFiles(t *testing.T) {
case string:
a := p.String(k)
if e != a {
t.Errorf("%s: expected %v, but received %v", path, e, a)
t.Errorf("%s: expected %v, but received %v for profile %v", path, e, a, profile)
}
case int:
a := p.Int(k)
Expand Down

0 comments on commit 02207b1

Please sign in to comment.