Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

internal/ini: Fix ini parser to handle empty values #2860

Merged
merged 12 commits into from
Oct 1, 2019
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