From 433d62ec0aeb779868a165cae27ad39305f972e0 Mon Sep 17 00:00:00 2001 From: Derek Collison Date: Thu, 7 Apr 2016 08:36:57 -0700 Subject: [PATCH] Parse IPs and raw strings in arrays properly --- conf/lex.go | 46 +++++++++++++++++++--------- conf/lex_test.go | 45 +++++++++++++++++++++++++++ server/configs/cluster.conf | 9 +++--- server/configs/seed.conf | 4 +-- server/configs/seed_tls.conf | 8 ++--- server/configs/srv_a.conf | 7 ++--- server/configs/srv_a_bcrypt.conf | 4 +-- server/configs/srv_b.conf | 7 ++--- server/configs/srv_b_bcrypt.conf | 4 +-- server/configs/test.conf | 2 +- server/configs/tls.conf | 2 +- server/configs/tls_bad_cipher.conf | 3 +- server/configs/tls_ciphers.conf | 2 +- server/configs/tls_empty_cipher.conf | 3 +- server/opts_test.go | 6 ++-- server/routes_test.go | 6 ++-- test/configs/auth_seed.conf | 4 +-- test/configs/cluster.conf | 4 +-- test/configs/override.conf | 4 +-- test/configs/seed.conf | 6 ++-- test/configs/srv_a.conf | 5 ++- test/configs/srv_a_tls.conf | 6 ++-- test/configs/srv_b.conf | 7 ++--- test/configs/srv_b_tls.conf | 6 ++-- 24 files changed, 127 insertions(+), 73 deletions(-) diff --git a/conf/lex.go b/conf/lex.go index ba34a854..27a427fa 100644 --- a/conf/lex.go +++ b/conf/lex.go @@ -1,4 +1,4 @@ -// Copyright 2013-2015 Apcera Inc. All rights reserved. +// Copyright 2013-2016 Apcera Inc. All rights reserved. // Customized heavily from // https://github.com/BurntSushi/toml/blob/master/lex.go, which is based on @@ -347,7 +347,7 @@ func lexValue(lx *lexer) stateFn { return lexBlock case isDigit(r): lx.backup() // avoid an extra state and use the same as above - return lexNumberOrDateStart + return lexNumberOrDateOrIPStart case r == '.': // special error case, be kind to users return lx.errorf("Floats must start with a digit, not '.'.") case isNL(r): @@ -376,8 +376,7 @@ func lexArrayValue(lx *lexer) stateFn { lx.backup() fallthrough case r == arrayValTerm: - return lx.errorf("Unexpected array value terminator '%v'.", - arrayValTerm) + return lx.errorf("Unexpected array value terminator '%v'.", arrayValTerm) case r == arrayEnd: return lexArrayEnd } @@ -603,15 +602,17 @@ func lexDubQuotedString(lx *lexer) stateFn { return lexDubQuotedString } -// lexString consumes the inner contents of a string. It assumes that the -// beginning '"' has already been consumed and ignored. +// lexString consumes the inner contents of a raw string. func lexString(lx *lexer) stateFn { r := lx.next() switch { case r == '\\': return lexStringEscape // Termination of non-quoted strings - case isNL(r) || r == eof || r == optValTerm || isWhitespace(r): + case isNL(r) || r == eof || r == optValTerm || + r == arrayValTerm || r == arrayEnd || + isWhitespace(r): + lx.backup() if lx.isBool() { lx.emit(itemBool) @@ -702,9 +703,9 @@ func lexStringBinary(lx *lexer) stateFn { return lexString } -// lexNumberOrDateStart consumes either a (positive) integer, float or datetime. -// It assumes that NO negative sign has been consumed. -func lexNumberOrDateStart(lx *lexer) stateFn { +// lexNumberOrDateStart consumes either a (positive) integer, a float, a datetime, or IP. +// It assumes that NO negative sign has been consumed, that is triggered above. +func lexNumberOrDateOrIPStart(lx *lexer) stateFn { r := lx.next() if !isDigit(r) { if r == '.' { @@ -712,11 +713,11 @@ func lexNumberOrDateStart(lx *lexer) stateFn { } return lx.errorf("Expected a digit but got '%v'.", r) } - return lexNumberOrDate + return lexNumberOrDateOrIP } -// lexNumberOrDate consumes either a (positive) integer, float or datetime. -func lexNumberOrDate(lx *lexer) stateFn { +// lexNumberOrDateOrIP consumes either a (positive) integer, float, datetime or IP. +func lexNumberOrDateOrIP(lx *lexer) stateFn { r := lx.next() switch { case r == '-': @@ -725,7 +726,7 @@ func lexNumberOrDate(lx *lexer) stateFn { } return lexDateAfterYear case isDigit(r): - return lexNumberOrDate + return lexNumberOrDateOrIP case r == '.': return lexFloatStart } @@ -786,7 +787,6 @@ func lexNumber(lx *lexer) stateFn { case r == '.': return lexFloatStart } - lx.backup() lx.emit(itemInteger) return lx.pop() @@ -811,11 +811,27 @@ func lexFloat(lx *lexer) stateFn { return lexFloat } + // Not a digit, if its another '.', need to see if we falsely assumed a float. + if r == '.' { + return lexIPAddr + } + lx.backup() lx.emit(itemFloat) return lx.pop() } +// lexIPAddr consumes IP addrs, like 127.0.0.1:4222 +func lexIPAddr(lx *lexer) stateFn { + r := lx.next() + if isDigit(r) || r == '.' || r == ':' { + return lexIPAddr + } + lx.backup() + lx.emit(itemString) + return lx.pop() +} + // lexCommentStart begins the lexing of a comment. It will emit // itemCommentStart and consume no characters, passing control to lexComment. func lexCommentStart(lx *lexer) stateFn { diff --git a/conf/lex_test.go b/conf/lex_test.go index bd917613..9e6ea55e 100644 --- a/conf/lex_test.go +++ b/conf/lex_test.go @@ -569,3 +569,48 @@ func TestBlockStringMultiLine(t *testing.T) { lx := lex(mlblockexample) expect(t, lx, expectedItems) } + +func TestUnquotedIPAddr(t *testing.T) { + expectedItems := []item{ + {itemKey, "listen", 1}, + {itemString, "127.0.0.1:4222", 1}, + {itemEOF, "", 1}, + } + lx := lex("listen: 127.0.0.1:4222") + expect(t, lx, expectedItems) + + expectedItems = []item{ + {itemKey, "listen", 1}, + {itemString, "127.0.0.1", 1}, + {itemEOF, "", 1}, + } + lx = lex("listen: 127.0.0.1") + expect(t, lx, expectedItems) + + expectedItems = []item{ + {itemKey, "listen", 1}, + {itemString, "apcera.me:80", 1}, + {itemEOF, "", 1}, + } + lx = lex("listen: apcera.me:80") + expect(t, lx, expectedItems) + + expectedItems = []item{ + {itemKey, "listen", 1}, + {itemString, ":80", 1}, + {itemEOF, "", 1}, + } + lx = lex("listen = :80") + expect(t, lx, expectedItems) + + expectedItems = []item{ + {itemKey, "listen", 1}, + {itemArrayStart, "", 1}, + {itemString, "localhost:4222", 1}, + {itemString, "localhost:4333", 1}, + {itemArrayEnd, "", 1}, + {itemEOF, "", 1}, + } + lx = lex("listen = [localhost:4222, localhost:4333]") + expect(t, lx, expectedItems) +} diff --git a/server/configs/cluster.conf b/server/configs/cluster.conf index 54198a2e..3ce5ece8 100644 --- a/server/configs/cluster.conf +++ b/server/configs/cluster.conf @@ -2,7 +2,7 @@ # Cluster config file port: 4242 -net: apcera.me # net interface +net: localhost authorization { user: derek @@ -14,7 +14,7 @@ pid_file: '/tmp/nats_cluster_test.pid' log_file: '/tmp/nats_cluster_test.log' cluster { - host: '127.0.0.1' + host: 127.0.0.1 port: 4244 authorization { @@ -28,9 +28,8 @@ cluster { # in their routes definitions from above. routes = [ - nats-route://foo:bar@apcera.me:4245 - nats-route://foo:bar@apcera.me:4246 + nats-route://foo:bar@localhost:4245 + nats-route://foo:bar@localhost:4246 ] } - diff --git a/server/configs/seed.conf b/server/configs/seed.conf index 147ad7a5..3813237b 100644 --- a/server/configs/seed.conf +++ b/server/configs/seed.conf @@ -3,11 +3,11 @@ # Cluster Seed Node port: 7222 -net: '127.0.0.1' +net: 127.0.0.1 http_port: 9222 cluster { - host: '127.0.0.1' + host: 127.0.0.1 port: 7248 } diff --git a/server/configs/seed_tls.conf b/server/configs/seed_tls.conf index 4e2d005e..5ba3c26b 100644 --- a/server/configs/seed_tls.conf +++ b/server/configs/seed_tls.conf @@ -3,14 +3,14 @@ # Cluster Seed Node port: 7222 -net: '127.0.0.1' +net: 127.0.0.1 http_port: 9222 cluster { - host: '127.0.0.1' + host: 127.0.0.1 port: 7248 - + tls { # Route cert cert_file: "../test/configs/certs/server-cert.pem" @@ -22,5 +22,5 @@ cluster { # Optional certificate authority verifying connected routes # Required when we have self-signed CA, etc. ca_file: "../test/configs/certs/ca.pem" - } + } } diff --git a/server/configs/srv_a.conf b/server/configs/srv_a.conf index 19b7601c..8ff19e6e 100644 --- a/server/configs/srv_a.conf +++ b/server/configs/srv_a.conf @@ -1,12 +1,12 @@ -# Copyright 2012-2015 Apcera Inc. All rights reserved. +# Copyright 2012-2016 Apcera Inc. All rights reserved. # Cluster Server A port: 7222 -net: '127.0.0.1' +net: 127.0.0.1 cluster { - host: '127.0.0.1' + host: 127.0.0.1 port: 7244 authorization { @@ -23,4 +23,3 @@ cluster { nats-route://ruser:top_secret@127.0.0.1:7246 ] } - diff --git a/server/configs/srv_a_bcrypt.conf b/server/configs/srv_a_bcrypt.conf index 5531fe1b..04927339 100644 --- a/server/configs/srv_a_bcrypt.conf +++ b/server/configs/srv_a_bcrypt.conf @@ -2,7 +2,7 @@ # Cluster Server A -host: '127.0.0.1' +host: 127.0.0.1 port: 7222 authorization { @@ -12,7 +12,7 @@ authorization { } cluster { - host: '127.0.0.1' + host: 127.0.0.1 port: 7244 authorization { diff --git a/server/configs/srv_b.conf b/server/configs/srv_b.conf index 154b0ffb..1b1b00bd 100644 --- a/server/configs/srv_b.conf +++ b/server/configs/srv_b.conf @@ -1,12 +1,12 @@ -# Copyright 2012-2015 Apcera Inc. All rights reserved. +# Copyright 2012-2016 Apcera Inc. All rights reserved. # Cluster Server B port: 7224 -net: '127.0.0.1' +net: 127.0.0.1 cluster { - host: '127.0.0.1' + host: 127.0.0.1 port: 7246 authorization { @@ -23,4 +23,3 @@ cluster { nats-route://ruser:top_secret@127.0.0.1:7244 ] } - diff --git a/server/configs/srv_b_bcrypt.conf b/server/configs/srv_b_bcrypt.conf index 587cdc40..9b21dc75 100644 --- a/server/configs/srv_b_bcrypt.conf +++ b/server/configs/srv_b_bcrypt.conf @@ -2,7 +2,7 @@ # Cluster Server B -host: '127.0.0.1' +host: 127.0.0.1 port: 7224 authorization { @@ -12,7 +12,7 @@ authorization { } cluster { - host: '127.0.0.1' + host: 127.0.0.1 port: 7246 authorization { diff --git a/server/configs/test.conf b/server/configs/test.conf index baf54187..65f6f7f4 100644 --- a/server/configs/test.conf +++ b/server/configs/test.conf @@ -2,7 +2,7 @@ # Simple config file port: 4242 -net: apcera.me # net interface +net: localhost http_port: 8222 diff --git a/server/configs/tls.conf b/server/configs/tls.conf index a94fb473..617d65e7 100644 --- a/server/configs/tls.conf +++ b/server/configs/tls.conf @@ -2,7 +2,7 @@ # Simple TLS config file port: 4443 -net: apcera.me # net interface +net: localhost tls { cert_file: "./configs/certs/server.pem" diff --git a/server/configs/tls_bad_cipher.conf b/server/configs/tls_bad_cipher.conf index 9f6ce58c..945aaea4 100644 --- a/server/configs/tls_bad_cipher.conf +++ b/server/configs/tls_bad_cipher.conf @@ -2,7 +2,7 @@ # Simple TLS config file port: 4443 -net: apcera.me # net interface +net: localhost tls { cert_file: "./configs/certs/server.pem" @@ -17,4 +17,3 @@ tls { "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", ] } - diff --git a/server/configs/tls_ciphers.conf b/server/configs/tls_ciphers.conf index 697cf0a3..4611bcd9 100644 --- a/server/configs/tls_ciphers.conf +++ b/server/configs/tls_ciphers.conf @@ -2,7 +2,7 @@ # Simple TLS config file port: 4443 -net: apcera.me # net interface +net: localhost tls { cert_file: "./configs/certs/server.pem" diff --git a/server/configs/tls_empty_cipher.conf b/server/configs/tls_empty_cipher.conf index 7c568c6e..ade32d95 100644 --- a/server/configs/tls_empty_cipher.conf +++ b/server/configs/tls_empty_cipher.conf @@ -2,7 +2,7 @@ # Simple TLS config file port: 4443 -net: apcera.me # net interface +net: localhost tls { cert_file: "./configs/certs/server.pem" @@ -13,4 +13,3 @@ tls { cipher_suites: [ ] } - diff --git a/server/opts_test.go b/server/opts_test.go index 52eb5f7b..38b7714c 100644 --- a/server/opts_test.go +++ b/server/opts_test.go @@ -48,7 +48,7 @@ func TestOptions_RandomPort(t *testing.T) { func TestConfigFile(t *testing.T) { golden := &Options{ - Host: "apcera.me", + Host: "localhost", Port: 4242, Username: "derek", Password: "bella", @@ -81,7 +81,7 @@ func TestConfigFile(t *testing.T) { func TestTLSConfigFile(t *testing.T) { golden := &Options{ - Host: "apcera.me", + Host: "localhost", Port: 4443, Username: "derek", Password: "buckley", @@ -168,7 +168,7 @@ func TestTLSConfigFile(t *testing.T) { func TestMergeOverrides(t *testing.T) { golden := &Options{ - Host: "apcera.me", + Host: "localhost", Port: 2222, Username: "derek", Password: "spooky", diff --git a/server/routes_test.go b/server/routes_test.go index f368c514..e6df6e95 100644 --- a/server/routes_test.go +++ b/server/routes_test.go @@ -19,7 +19,7 @@ func TestRouteConfig(t *testing.T) { } golden := &Options{ - Host: "apcera.me", + Host: "localhost", Port: 4242, Username: "derek", Password: "bella", @@ -34,8 +34,8 @@ func TestRouteConfig(t *testing.T) { } // Setup URLs - r1, _ := url.Parse("nats-route://foo:bar@apcera.me:4245") - r2, _ := url.Parse("nats-route://foo:bar@apcera.me:4246") + r1, _ := url.Parse("nats-route://foo:bar@localhost:4245") + r2, _ := url.Parse("nats-route://foo:bar@localhost:4246") golden.Routes = []*url.URL{r1, r2} diff --git a/test/configs/auth_seed.conf b/test/configs/auth_seed.conf index ea80850a..23882704 100644 --- a/test/configs/auth_seed.conf +++ b/test/configs/auth_seed.conf @@ -1,9 +1,9 @@ -# Copyright 2015 Apcera Inc. All rights reserved. +# Copyright 2015-2016 Apcera Inc. All rights reserved. # Cluster Seed Node port: 4222 -net: '127.0.0.1' +net: 127.0.0.1 http_port: 8222 diff --git a/test/configs/cluster.conf b/test/configs/cluster.conf index c9fd0eba..bdb3abd2 100644 --- a/test/configs/cluster.conf +++ b/test/configs/cluster.conf @@ -1,8 +1,8 @@ -# Copyright 2012-2015 Apcera Inc. All rights reserved. +# Copyright 2012-2016 Apcera Inc. All rights reserved. # Cluster config file -host: "127.0.0.1" +host: 127.0.0.1 port: 4242 cluster { diff --git a/test/configs/override.conf b/test/configs/override.conf index 88d351b7..a8917d7d 100644 --- a/test/configs/override.conf +++ b/test/configs/override.conf @@ -1,8 +1,8 @@ -# Copyright 2015 Apcera Inc. All rights reserved. +# Copyright 2015-2016 Apcera Inc. All rights reserved. # Config file to test overrides to client -host: "127.0.0.1" +host: 127.0.0.1 port: 4224 # maximum payload diff --git a/test/configs/seed.conf b/test/configs/seed.conf index b0bf45a6..dae7cea1 100644 --- a/test/configs/seed.conf +++ b/test/configs/seed.conf @@ -1,13 +1,13 @@ -# Copyright 2015 Apcera Inc. All rights reserved. +# Copyright 2015-2016 Apcera Inc. All rights reserved. # Cluster Seed Node port: 4222 -net: '127.0.0.1' +net: 127.0.0.1 http_port: 8222 cluster { - host: '127.0.0.1' + host: 127.0.0.1 port: 4248 } diff --git a/test/configs/srv_a.conf b/test/configs/srv_a.conf index 6316c8e0..917925b9 100644 --- a/test/configs/srv_a.conf +++ b/test/configs/srv_a.conf @@ -1,9 +1,9 @@ -# Copyright 2012-2013 Apcera Inc. All rights reserved. +# Copyright 2012-2016 Apcera Inc. All rights reserved. # Cluster Server A port: 4222 -net: '127.0.0.1' +net: 127.0.0.1 cluster { host: '127.0.0.1' @@ -23,4 +23,3 @@ cluster { nats-route://ruser:top_secret@127.0.0.1:4246 ] } - diff --git a/test/configs/srv_a_tls.conf b/test/configs/srv_a_tls.conf index fc16e5ce..d6de3087 100644 --- a/test/configs/srv_a_tls.conf +++ b/test/configs/srv_a_tls.conf @@ -1,12 +1,12 @@ -# Copyright 2012-2015 Apcera Inc. All rights reserved. +# Copyright 2012-2016 Apcera Inc. All rights reserved. # Cluster Server A -host: '127.0.0.1' +host: 127.0.0.1 port: 4222 cluster { - host: '127.0.0.1' + host: 127.0.0.1 port: 4244 tls { diff --git a/test/configs/srv_b.conf b/test/configs/srv_b.conf index 45941c9f..3d8f30d4 100644 --- a/test/configs/srv_b.conf +++ b/test/configs/srv_b.conf @@ -1,12 +1,12 @@ -# Copyright 2012-2013 Apcera Inc. All rights reserved. +# Copyright 2012-2016 Apcera Inc. All rights reserved. # Cluster Server B port: 4224 -net: '127.0.0.1' +net: 127.0.0.1 cluster { - host: '127.0.0.1' + host: 127.0.0.1 port: 4246 authorization { @@ -23,4 +23,3 @@ cluster { nats-route://ruser:top_secret@127.0.0.1:4244 ] } - diff --git a/test/configs/srv_b_tls.conf b/test/configs/srv_b_tls.conf index 2a9fa707..571a5852 100644 --- a/test/configs/srv_b_tls.conf +++ b/test/configs/srv_b_tls.conf @@ -1,12 +1,12 @@ -# Copyright 2012-2015 Apcera Inc. All rights reserved. +# Copyright 2012-2016 Apcera Inc. All rights reserved. # Cluster Server B -host: '127.0.0.1' +host: 127.0.0.1 port: 4224 cluster { - host: '127.0.0.1' + host: 127.0.0.1 port: 4246 tls {