Repository: elastic/go-ucfg
Pull request #192 (2022-05-02 20:11:04)

Add flag to ignore commas when parsing.
The new flag stops the parser from building arrays automatically when
top level elements are separated with commas. This flag converts parsing
into an actual no-op, passing through the input unmodified. This mode is
necessary when parsing values that may legitimately contain special
characters, like secrets.

This is the first step in fixing https://github.com/elastic/beats/issues/29789. A follow up change in beats will follow to start ignoring commas when loading from the keystore.

Draft beats PR with a failing test that will pass with these changes: https://github.com/elastic/beats/pull/31487

elasticmachine: 
## :broken_heart: Build Failed


<!-- BUILD BADGES-->
> _the below badges are clickable and redirect to their specific view in the CI or DOCS_
[![Pipeline View](https://img.shields.io/badge/pipeline-pipeline%20-green)](https://beats-ci.elastic.co/blue/organizations/jenkins/Library%2Fgo-ucfg-mbp%2FPR-192/detail/PR-192/1//pipeline) [![Test View](https://img.shields.io/badge/test-test-green)](https://beats-ci.elastic.co/blue/organizations/jenkins/Library%2Fgo-ucfg-mbp%2FPR-192/detail/PR-192/1//tests) [![Changes](https://img.shields.io/badge/changes-changes-green)](https://beats-ci.elastic.co/blue/organizations/jenkins/Library%2Fgo-ucfg-mbp%2FPR-192/detail/PR-192/1//changes) [![Artifacts](https://img.shields.io/badge/artifacts-artifacts-yellow)](https://beats-ci.elastic.co/blue/organizations/jenkins/Library%2Fgo-ucfg-mbp%2FPR-192/detail/PR-192/1//artifacts) [![preview](https://img.shields.io/badge/docs-preview-yellowgreen)](http://go-ucfg_192.docs-preview.app.elstc.co/diff)  [![preview](https://img.shields.io/badge/elastic-observability-blue)](https://ci-stats.elastic.co/app/apm/services/beats-ci/transactions/view?rangeFrom=2022-05-02T20:01:20.605Z&rangeTo=2022-05-02T20:21:20.605Z&transactionName=Library/go-ucfg-mbp/PR-{number}&transactionType=job&latencyAggregationType=avg&traceId=541af85b4751aeff47e606224cfc8557&transactionId=84d0297e70e7c3a8)

<!-- BUILD SUMMARY-->
<details><summary>Expand to view the summary</summary>
<p>

#### Build stats




* Start Time: 2022-05-02T20:11:20.605+0000


* Duration: 2 min 12 sec





</p>
</details>

<!-- TEST RESULTS IF ANY-->


<!-- STEPS ERRORS IF ANY -->












### Steps errors [![1](https://img.shields.io/badge/1%20-red)](https://beats-ci.elastic.co/blue/organizations/jenkins/Library%2Fgo-ucfg-mbp%2FPR-192/detail/PR-192/1//pipeline)
  <details><summary>Expand to view the steps failures</summary>
  <p>


  
  
  
  
##### `.ci/check.sh`
<ul>
<li>Took 0 min 5 sec . View more details <a href="https://beats-ci.elastic.co//blue/rest/organizations/jenkins/pipelines/Library/pipelines/go-ucfg-mbp/pipelines/PR-192/runs/1/steps/121/log/?start=0">here</a></li>
<li>Description: <code>.ci/check.sh</code></l1>
</ul>
  
  </p>
  </details>




<!--COMMENT_GENERATED_WITH_ID_comment.id-->

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 64d419b..3541cab 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,14 @@ This project adheres to [Semantic Versioning](http://semver.org/).
 
 ### Fixed
 
+## [0.8.5]
+
+### Added
+- Added new parse.Config flag to disable using commas to imply arrays. #192
+
+### Changed
+- The parse.NoopConfig disables using commas to imply arrays by default. #192
+
 ## [0.8.4]
 
 ### Fixed
diff --git a/NOTICE.txt b/NOTICE.txt
index f6c9af3..5dde3ce 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -1,4 +1,4 @@
-Copyright 2016-2021 Elasticsearch BV
+Copyright 2016-2022 Elasticsearch BV
 
 This product includes software developed by The Apache Software
 Foundation (http://www.apache.org/).
diff --git a/parse/parse.go b/parse/parse.go
index 5fafefd..16a67e8 100644
--- a/parse/parse.go
+++ b/parse/parse.go
@@ -27,10 +27,17 @@ import (
 
 // Config allows enabling and disabling parser features.
 type Config struct {
-	Array        bool
-	Object       bool
+	// Enables parsing arrays from values enclosed in [].
+	Array bool
+	// Enables parsing objects enclosed in {}.
+	Object bool
+	// Enables parsing double quoted strings, where values are escaped.
 	StringDQuote bool
+	// Enables parsing single quotes strings, where no values are escaped.
 	StringSQuote bool
+	// Enables ignoring commas as a shortcut for building arrays: a,b parses to [a,b].
+	// The comma array syntax is enabled by default for backwards compatibility.
+	IgnoreCommas bool
 }
 
 // DefaultConfig is the default config with all parser features enabled.
@@ -55,6 +62,7 @@ var NoopConfig = Config{
 	Object:       false,
 	StringDQuote: false,
 	StringSQuote: false,
+	IgnoreCommas: true,
 }
 
 type flagParser struct {
@@ -125,7 +133,13 @@ func (p *flagParser) parse() (interface{}, error) {
 	var values []interface{}
 
 	for {
-		v, err := p.parseValue(toplevelStopSet)
+		// Enable building arrays when commas separate top level elements by default.
+		stopSet := toplevelStopSet
+		if p.cfg.IgnoreCommas {
+			stopSet = ""
+		}
+
+		v, err := p.parseValue(stopSet)
 		if err != nil {
 			return nil, err
 		}


Test patch:
diff --git a/parse/parse_test.go b/parse/parse_test.go
index ab3899a..8db856e 100644
--- a/parse/parse_test.go
+++ b/parse/parse_test.go
@@ -722,60 +722,36 @@ func TestFlagValueParsingWithNoop(t *testing.T) {
 		{`[]`, `[]`},
 		{
 			`a,b,c`,
-			[]interface{}{"a", "b", "c"},
+			`a,b,c`,
 		},
 		{
 			`C:\Windows\Path1,C:\Windows\Path2`,
-			[]interface{}{
-				`C:\Windows\Path1`,
-				`C:\Windows\Path2`,
-			},
+			`C:\Windows\Path1,C:\Windows\Path2`,
 		},
 		{
 			`[array, 1, true, "abc"]`,
-			[]interface{}{"[array", uint64(1), true, `"abc"]`},
+			`[array, 1, true, "abc"]`,
 		},
 		{
 			`[test, [1,2,3], on]`,
-			[]interface{}{
-				"[test",
-				"[1",
-				uint64(2),
-				"3]",
-				"on]",
-			},
+			`[test, [1,2,3], on]`,
 		},
 		{
 			`[host1:1234, host2:1234]`,
-			[]interface{}{
-				"[host1:1234",
-				"host2:1234]",
-			},
+			`[host1:1234, host2:1234]`,
 		},
 
 		// test dictionaries:
 		{`{}`, `{}`},
-		{`{'key1': true,
-       "key2": 1,
-       key 3: ['test', "test2", off],
-	   nested key: {"a" : 2}}`,
-			[]interface{}{
-				`{'key1': true`,
-				`"key2": 1`,
-				`key 3: ['test'`,
-				`"test2"`,
-				`off]`,
-				`nested key: {"a" : 2}}`,
-			},
+		{
+			`{'key1': true, "key2": 1, key 3: ['test', "test2", off], nested key: {"a" : 2}}`,
+			`{'key1': true, "key2": 1, key 3: ['test', "test2", off], nested key: {"a" : 2}}`,
 		},
 
 		// array of top-level dictionaries
 		{
 			`{key: 1},{key: 2}`,
-			[]interface{}{
-				"{key: 1}",
-				"{key: 2}",
-			},
+			`{key: 1},{key: 2}`,
 		},
 	}