internal/number: fix bug in info lookup

fallback needs to be computed for both modes.
Latn data is elided from the tables, so check
for latin script at the root.

Change-Id: I6db954b9b76761380fec3b90fde962449536fa23
Reviewed-on: https://go-review.googlesource.com/81755
Run-TryBot: Marcel van Lohuizen <mpvl@golang.org>
Reviewed-by: Nigel Tao <nigeltao@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/internal/number/number.go b/internal/number/number.go
index ea341c7..336c0d8 100644
--- a/internal/number/number.go
+++ b/internal/number/number.go
@@ -31,9 +31,9 @@
 	if !ok {
 		// Take the value for the default numbering system. This is by far the
 		// most common case as an alternative numbering system is hardly used.
-		if p&0x80 == 0 {
+		if p&0x80 == 0 { // Latn digits.
 			pSymIndex = p
-		} else {
+		} else { // Non-Latn or multiple numbering systems.
 			// Take the first entry from the alternatives list.
 			data := langToAlt[p&^0x80]
 			pSymIndex = data.symIndex
@@ -43,8 +43,22 @@
 		langIndex := compactIndex
 		ns := system
 	outerLoop:
-		for {
-			if p&0x80 == 0 {
+		for ; ; p = langToDefaults[langIndex] {
+			if langIndex == 0 {
+				// The CLDR root defines full symbol information for all
+				// numbering systems (even though mostly by means of
+				// aliases).
+				// Fall back to the default entry for Latn if there is
+				// no data for the numbering system of this language.
+				if ns == 0 {
+					break
+				}
+				// Fall back to Latin and start from the original
+				// language. See
+				// http://unicode.org/reports/tr35/#Locale_Inheritance.
+				ns = numLatn
+				langIndex = compactIndex
+			} else if p&0x80 == 0 {
 				if ns == 0 {
 					// The index directly points to the symbol data.
 					pSymIndex = p
@@ -52,30 +66,16 @@
 				}
 				// Move to the parent and retry.
 				langIndex = int(internal.Parent[langIndex])
-			}
-			// The index points to a list of symbol data indexes.
-			for _, e := range langToAlt[p&^0x80:] {
-				if int(e.compactTag) != langIndex {
-					if langIndex == 0 {
-						// The CLDR root defines full symbol information for all
-						// numbering systems (even though mostly by means of
-						// aliases). This means that we will never fall back to
-						// the default of the language. Also, the loop is
-						// guaranteed to terminate as a consequence.
-						ns = numLatn
-						// Fall back to Latin and start from the original
-						// language. See
-						// http://unicode.org/reports/tr35/#Locale_Inheritance.
-						langIndex = compactIndex
-					} else {
+			} else {
+				// The index points to a list of symbol data indexes.
+				for _, e := range langToAlt[p&^0x80:] {
+					if int(e.compactTag) != langIndex {
 						// Fall back to parent.
 						langIndex = int(internal.Parent[langIndex])
+					} else if e.system == ns {
+						pSymIndex = e.symIndex
+						break outerLoop
 					}
-					break
-				}
-				if e.system == ns {
-					pSymIndex = e.symIndex
-					break outerLoop
 				}
 			}
 		}
diff --git a/internal/number/number_test.go b/internal/number/number_test.go
index 8717ead..cbc28ab 100644
--- a/internal/number/number_test.go
+++ b/internal/number/number_test.go
@@ -31,6 +31,10 @@
 		{"de-CH-oxendict", SymGroup, "’", '9'},       // inherits from de-CH (no compact index)
 		{"de-CH-u-nu-deva", SymGroup, "’", '\u096f'}, // miss -> latn -> de-CH
 
+		{"bn-u-nu-beng", SymGroup, ",", '\u09ef'},
+		{"bn-u-nu-deva", SymGroup, ",", '\u096f'},
+		{"bn-u-nu-latn", SymGroup, ",", '9'},
+
 		{"pa", SymExponential, "E", '9'},
 
 		// "×۱۰^" -> U+00d7 U+06f1 U+06f0^"