From af1b449602b360091e191a58abde2f246d8b0f1d Mon Sep 17 00:00:00 2001
From: Jeffory Orrok <74276873+jeffory-orrok@users.noreply.github.com>
Date: Thu, 29 Apr 2021 01:49:40 -0600
Subject: [PATCH] fix: allow for an optional semicolon where there is an
 optional comma in parseOptionValue (#1571)

* allow for an optional semicolon where there is an optional comma in parseOptionValue

* set allowShortCircuit to true to prevent no-unused-expressions error

* add test for semicolon

Co-authored-by: Alexander Fenster <fenster@google.com>
---
 config/eslint.json               | 2 +-
 src/parse.js                     | 2 +-
 tests/comp_options-textformat.js | 2 ++
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/config/eslint.json b/config/eslint.json
index 191a44180..2800db370 100644
--- a/config/eslint.json
+++ b/config/eslint.json
@@ -72,7 +72,7 @@
         "no-self-compare": 1,
         "no-throw-literal": 1,
         "no-unmodified-loop-condition": 1,
-        "no-unused-expressions": 1,
+        "no-unused-expressions": ["error", { "allowShortCircuit": true }],
         "no-useless-call": 1,
         "no-useless-concat": 1,
         "no-useless-escape": 1,
diff --git a/src/parse.js b/src/parse.js
index 144feed29..de2993815 100644
--- a/src/parse.js
+++ b/src/parse.js
@@ -611,7 +611,7 @@ function parse(source, root, options) {
                 if (prevValue)
                     value = [].concat(prevValue).concat(value);
                 result[propName] = value;
-                skip(",", true);
+                skip(",", true) || skip(";", true);
             }
             return result;
         }
diff --git a/tests/comp_options-textformat.js b/tests/comp_options-textformat.js
index b7788e48f..325aaa958 100644
--- a/tests/comp_options-textformat.js
+++ b/tests/comp_options-textformat.js
@@ -15,6 +15,7 @@ message Test {\
   string value = 1 [(my_options) = { a: \"foo\" b: \"bar\" }];\
   string value2 = 2 [(my_options) = { a: \"foo\" b { c: \"bar\" } }];\
   string value3 = 3 [(my_options) = { a: \"foo\", b: \"bar\" }];\
+  string value4 = 4 [(my_options) = { a: \"foo\"; b: \"bar\" }];\
 }";
 
 tape.test("options in textformat", function(test) {
@@ -23,5 +24,6 @@ tape.test("options in textformat", function(test) {
     test.same(Test.fields.value.options, { "(my_options).a": "foo", "(my_options).b": "bar" }, "should parse correctly");
     test.same(Test.fields.value2.options, { "(my_options).a": "foo", "(my_options).b.c": "bar" }, "should parse correctly when nested");
     test.same(Test.fields.value3.options, { "(my_options).a": "foo", "(my_options).b": "bar" }, "should parse correctly when comma-separated");
+    test.same(Test.fields.value4.options, { "(my_options).a": "foo", "(my_options).b": "bar" }, "should parse correctly when semicolon-separated");
     test.end();
 });