Improved color validation - now with fixes and a table driven test

This commit is contained in:
ErikEk 2018-11-04 03:00:19 +01:00
parent b600985063
commit f36c58acd7
2 changed files with 39 additions and 25 deletions

@ -10,6 +10,7 @@ import (
"math/big" "math/big"
"net" "net"
"path/filepath" "path/filepath"
"regexp"
"strconv" "strconv"
"sync" "sync"
"sync/atomic" "sync/atomic"
@ -70,6 +71,10 @@ var (
// ErrServerShuttingDown indicates that the server is in the process of // ErrServerShuttingDown indicates that the server is in the process of
// gracefully exiting. // gracefully exiting.
ErrServerShuttingDown = errors.New("server is shutting down") ErrServerShuttingDown = errors.New("server is shutting down")
// validColorRegexp is a regexp that lets you check if a particular
// color string matches the standard hex color format #RRGGBB.
validColorRegexp = regexp.MustCompile("^#[A-Fa-f0-9]{6}$")
) )
// server is the main server of the Lightning Network Daemon. The server houses // server is the main server of the Lightning Network Daemon. The server houses
@ -2821,8 +2826,10 @@ func (s *server) Peers() []*peer {
// form "#RRGGBB", parses the hex color values, and returns a color.RGBA // form "#RRGGBB", parses the hex color values, and returns a color.RGBA
// struct of the same color. // struct of the same color.
func parseHexColor(colorStr string) (color.RGBA, error) { func parseHexColor(colorStr string) (color.RGBA, error) {
if len(colorStr) != 7 || colorStr[0] != '#' { // Check if the hex color string is a valid color representation.
return color.RGBA{}, errors.New("Color must be in format #RRGGBB") if !validColorRegexp.MatchString(colorStr) {
return color.RGBA{}, errors.New("Color must be specified " +
"using a hexadecimal value in the form #RRGGBB")
} }
// Decode the hex color string to bytes. // Decode the hex color string to bytes.

@ -5,32 +5,39 @@ package main
import "testing" import "testing"
func TestParseHexColor(t *testing.T) { func TestParseHexColor(t *testing.T) {
empty := "" var colorTestCases = []struct {
color, err := parseHexColor(empty) test string
if err == nil { valid bool // If valid format
t.Fatalf("Empty color string should return error, but did not") R byte
G byte
B byte
}{
{"#123", false, 0, 0, 0},
{"#1234567", false, 0, 0, 0},
{"$123456", false, 0, 0, 0},
{"#12345+", false, 0, 0, 0},
{"#fFGG00", false, 0, 0, 0},
{"", false, 0, 0, 0},
{"#123456", true, 0x12, 0x34, 0x56},
{"#C0FfeE", true, 0xc0, 0xff, 0xee},
} }
tooLong := "#1234567" // Perform the table driven tests.
color, err = parseHexColor(tooLong) for _, ct := range colorTestCases {
if err == nil {
t.Fatalf("Invalid color string %s should return error, but did not",
tooLong)
}
invalidFormat := "$123456" color, err := parseHexColor(ct.test)
color, err = parseHexColor(invalidFormat) if !ct.valid && err == nil {
if err == nil { t.Fatalf("Invalid color string: %s, should return "+
t.Fatalf("Invalid color string %s should return error, but did not", "error, but did not", ct.test)
invalidFormat) }
}
valid := "#C0FfeE" if ct.valid && err != nil {
color, err = parseHexColor(valid) t.Fatalf("Color %s valid to parse: %s", ct.test, err)
if err != nil { }
t.Fatalf("Color %s valid to parse: %s", valid, err)
} // Ensure that the string to hex decoding is working properly.
if color.R != 0xc0 || color.G != 0xff || color.B != 0xee { if color.R != ct.R || color.G != ct.G || color.B != ct.B {
t.Fatalf("Color %s incorrectly parsed as %v", valid, color) t.Fatalf("Color %s incorrectly parsed as %v", ct.test, color)
}
} }
} }