From b3dd86a21edd9d272064a2a80815f6ad14c2d250 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Mon, 30 Jun 2014 15:17:53 -0700 Subject: [PATCH] Add validation primitives to util Part 2 in a series of changes towards data validation. --- pkg/util/validation.go | 53 ++++++++++++++++ pkg/util/validation_test.go | 122 ++++++++++++++++++++++++++++++++++++ 2 files changed, 175 insertions(+) create mode 100644 pkg/util/validation.go create mode 100644 pkg/util/validation_test.go diff --git a/pkg/util/validation.go b/pkg/util/validation.go new file mode 100644 index 00000000000..44a754b9524 --- /dev/null +++ b/pkg/util/validation.go @@ -0,0 +1,53 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package util + +import ( + "regexp" +) + +var dnsLabelFmt string = "[a-z0-9]([-a-z0-9]*[a-z0-9])?" +var dnsLabelRegexp *regexp.Regexp = regexp.MustCompile("^" + dnsLabelFmt + "$") + +// IsDNSLabel tests for a string that conforms to the definition of a label in +// DNS (RFC 1035/1123). This checks the format, but not the length. +func IsDNSLabel(value string) bool { + return dnsLabelRegexp.MatchString(value) +} + +var dnsSubdomainFmt string = dnsLabelFmt + "(\\." + dnsLabelFmt + ")*" +var dnsSubdomainRegexp *regexp.Regexp = regexp.MustCompile("^" + dnsSubdomainFmt + "$") + +// IsDNSSubdomain tests for a string that conforms to the definition of a +// subdomain in DNS (RFC 1035/1123). This checks the format, but not the length. +func IsDNSSubdomain(value string) bool { + return dnsSubdomainRegexp.MatchString(value) +} + +var cIdentifierFmt string = "[A-Za-z_][A-Za-z0-9_]*" +var cIdentifierRegexp *regexp.Regexp = regexp.MustCompile("^" + cIdentifierFmt + "$") + +// IsCIdentifier tests for a string that conforms the definition of an identifier +// in C. This checks the format, but not the length. +func IsCIdentifier(value string) bool { + return cIdentifierRegexp.MatchString(value) +} + +// IsValidPortNum tests that the argument is a valid, non-zero port number. +func IsValidPortNum(port int) bool { + return 0 < port && port < 65536 +} diff --git a/pkg/util/validation_test.go b/pkg/util/validation_test.go new file mode 100644 index 00000000000..2f6ef29477f --- /dev/null +++ b/pkg/util/validation_test.go @@ -0,0 +1,122 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package util + +import ( + "testing" +) + +func TestIsDNSLabel(t *testing.T) { + goodValues := []string{ + "a", "ab", "abc", "a1", "a-1", "a--1--2--b", + "0", "01", "012", "1a", "1-a", "1--a--b--2", + } + for _, val := range goodValues { + if !IsDNSLabel(val) { + t.Errorf("expected true for '%s'", val) + } + } + + badValues := []string{ + "", "A", "ABC", "aBc", "A1", "A-1", "1-A", + "-", "a-", "-a", "1-", "-1", + "_", "a_", "_a", "a_b", "1_", "_1", "1_2", + ".", "a.", ".a", "a.b", "1.", ".1", "1.2", + " ", "a ", " a", "a b", "1 ", " 1", "1 2", + } + for _, val := range badValues { + if IsDNSLabel(val) { + t.Errorf("expected false for '%s'", val) + } + } +} + +func TestIsDNSSubdomain(t *testing.T) { + goodValues := []string{ + "a", "ab", "abc", "a1", "a-1", "a--1--2--b", + "0", "01", "012", "1a", "1-a", "1--a--b--2", + "a.a", "ab.a", "abc.a", "a1.a", "a-1.a", "a--1--2--b.a", + "a.1", "ab.1", "abc.1", "a1.1", "a-1.1", "a--1--2--b.1", + "0.a", "01.a", "012.a", "1a.a", "1-a.a", "1--a--b--2", + "0.1", "01.1", "012.1", "1a.1", "1-a.1", "1--a--b--2.1", + "a.b.c.d.e", "aa.bb.cc.dd.ee", "1.2.3.4.5", "11.22.33.44.55", + } + for _, val := range goodValues { + if !IsDNSSubdomain(val) { + t.Errorf("expected true for '%s'", val) + } + } + + badValues := []string{ + "", "A", "ABC", "aBc", "A1", "A-1", "1-A", + "-", "a-", "-a", "1-", "-1", + "_", "a_", "_a", "a_b", "1_", "_1", "1_2", + ".", "a.", ".a", "a..b", "1.", ".1", "1..2", + " ", "a ", " a", "a b", "1 ", " 1", "1 2", + "A.a", "aB.a", "ab.A", "A1.a", "a1.A", + "A.1", "aB.1", "A1.1", "1A.1", + "0.A", "01.A", "012.A", "1A.a", "1a.A", + "A.B.C.D.E", "AA.BB.CC.DD.EE", "a.B.c.d.e", "aa.bB.cc.dd.ee", + "a@b", "a,b", "a_b", "a;b", + "a:b", "a%b", "a?b", "a$b", + } + for _, val := range badValues { + if IsDNSSubdomain(val) { + t.Errorf("expected false for '%s'", val) + } + } +} + +func TestIsCIdentifier(t *testing.T) { + goodValues := []string{ + "a", "ab", "abc", "a1", "_a", "a_", "a_b", "a_1", "a__1__2__b", "__abc_123", + "A", "AB", "AbC", "A1", "_A", "A_", "A_B", "A_1", "A__1__2__B", "__123_ABC", + } + for _, val := range goodValues { + if !IsCIdentifier(val) { + t.Errorf("expected true for '%s'", val) + } + } + + badValues := []string{ + "", "1", "123", "1a", + "-", "a-", "-a", "1-", "-1", "1_", "1_2", + ".", "a.", ".a", "a.b", "1.", ".1", "1.2", + " ", "a ", " a", "a b", "1 ", " 1", "1 2", + } + for _, val := range badValues { + if IsCIdentifier(val) { + t.Errorf("expected false for '%s'", val) + } + } +} + +func TestIsValidPortNum(t *testing.T) { + goodValues := []int{1, 2, 1000, 16384, 32768, 65535} + for _, val := range goodValues { + if !IsValidPortNum(val) { + t.Errorf("expected true for '%s'", val) + } + } + + badValues := []int{0, -1, 65536, 100000} + for _, val := range badValues { + if IsValidPortNum(val) { + t.Errorf("expected false for '%s'", val) + } + } +}