From 381b1538aa3b84d6d185dc7fbf3f4c0d2dcfa6d5 Mon Sep 17 00:00:00 2001
From: Ian Bishop <ianbishop@pace7.com>
Date: Sat, 1 Jul 2017 10:40:10 +1000
Subject: [PATCH] Fix handling of files

- New() should return an error so the caller knows what went wrong
- don't panic on empty file
- close file after finished reading
- update tests to match
---
 ouitools.go      | 16 ++++++++++++----
 ouitools_test.go | 19 ++++++++++---------
 2 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/ouitools.go b/ouitools.go
index 38bc76e..4c9fc68 100644
--- a/ouitools.go
+++ b/ouitools.go
@@ -4,6 +4,7 @@ package ouidb
 import (
 	"bufio"
 	"errors"
+	"fmt"
 	"os"
 	"regexp"
 	"sort"
@@ -11,6 +12,8 @@ import (
 	"strings"
 )
 
+const ouiReStr = `^(\S+)\t+(\S+)(\s+#\s+(\S.*))?`
+
 var ErrInvalidMACAddress = errors.New("invalid MAC address")
 
 // Helper functions
@@ -172,8 +175,9 @@ func (m *OuiDB) load(path string) error {
 	if err != nil {
 		return (err)
 	}
+	defer file.Close()
 
-	fieldsRe := regexp.MustCompile(`^(\S+)\t+(\S+)(\s+#\s+(\S.*))?`)
+	fieldsRe := regexp.MustCompile(ouiReStr)
 
 	scanner := bufio.NewScanner(file)
 	for scanner.Scan() {
@@ -238,20 +242,24 @@ func (m *OuiDB) load(path string) error {
 		return err
 	}
 
+	if len(m.blocks48) == 0 && len(m.blocks24) == 0 {
+		return fmt.Errorf("database is empty")
+	}
+
 	return nil
 }
 
 // New returns a new OUI database loaded from the specified file.
-func New(file string) *OuiDB {
+func New(file string) (*OuiDB, error) {
 	db := &OuiDB{}
 	if err := db.load(file); err != nil {
-		return nil
+		return nil, err
 	}
 
 	sort.Sort(db.blocks48)
 	sort.Sort(db.blocks24)
 
-	return db
+	return db, nil
 }
 
 func (db *OuiDB) blockLookup(address [6]byte) addressBlock {
diff --git a/ouitools_test.go b/ouitools_test.go
index f635750..5c25714 100644
--- a/ouitools_test.go
+++ b/ouitools_test.go
@@ -43,23 +43,24 @@ func invalid(t *testing.T, mac string) {
 }
 
 func TestInitialization(t *testing.T) {
-	db = New("oui.txt")
-	if db == nil {
-		t.Fatal("can't load database file oui.txt")
+	var err error
+	db, err = New("oui.txt")
+	if err != nil {
+		t.Fatalf("can't load database file oui.txt: %s", err)
 	}
 }
 
 func TestMissingDBFile(t *testing.T) {
-	db := New("bad-file")
-	if db != nil {
-		t.Fatal("didn't return nil on missing file")
+	_, err := New("bad-file")
+	if err == nil {
+		t.Fatal("didn't return err on missing file")
 	}
 }
 
 func TestInvalidDBFile(t *testing.T) {
-	db := New("ouidb_test.go")
-	if db != nil {
-		t.Fatal("didn't return nil on bad file")
+	_, err := New("ouidb_test.go")
+	if err == nil {
+		t.Fatal("didn't return err on bad file")
 	}
 }