Index: hbase-common/src/main/java/org/apache/hadoop/hbase/TableName.java =================================================================== --- hbase-common/src/main/java/org/apache/hadoop/hbase/TableName.java (revision 1610610) +++ hbase-common/src/main/java/org/apache/hadoop/hbase/TableName.java (working copy) @@ -136,7 +136,7 @@ int namespaceDelimIndex = com.google.common.primitives.Bytes.lastIndexOf(tableName, (byte) NAMESPACE_DELIM); - if (namespaceDelimIndex == 0 || namespaceDelimIndex == -1){ + if (namespaceDelimIndex < 0){ isLegalTableQualifierName(tableName); } else { isLegalNamespaceName(tableName, 0, namespaceDelimIndex); @@ -217,6 +217,11 @@ "'alphanumeric characters': i.e. [a-zA-Z_0-9]: " + Bytes.toString(namespaceName, offset, length)); } + if(offset == length) + throw new IllegalArgumentException("Illegal character <" + namespaceName[offset] + + "> at " + offset + ". Namespaces can only contain " + + "'alphanumeric characters': i.e. [a-zA-Z_0-9]: " + Bytes.toString(namespaceName, + offset, length)); } public byte[] getName() { Index: hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestTableName.java =================================================================== --- hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestTableName.java (revision 1610610) +++ hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestTableName.java (working copy) @@ -17,13 +17,20 @@ */ package org.apache.hadoop.hbase.util; +import static org.junit.Assert.fail; + +import org.apache.hadoop.hbase.SmallTests; import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.util.Bytes; +import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.rules.TestWatcher; import org.junit.runner.Description; /** * Returns a {@code byte[]} containing the name of the currently running test method. */ +@Category(SmallTests.class) public class TestTableName extends TestWatcher { private TableName tableName; @@ -38,4 +45,51 @@ public TableName getTableName() { return tableName; } + + String emptyTableNames[] ={"", " "}; + String invalidNamespace[] = {":a", "%:a"}; + String legalTableNames[] = { "foo", "with-dash_under.dot", "_under_start_ok", + "with-dash.with_underscore", "02-01-2012.my_table_01-02", "xyz._mytable_", "9_9_0.table_02" + , "dot1.dot2.table", "new.-mytable", "with-dash.with.dot", "legal..t2", "legal..legal.t2", + "trailingdots..", "trailing.dots...", "ns:mytable", "ns:_mytable_", "ns:my_table_01-02"}; + String illegalTableNames[] = { ".dot_start_illegal", "-dash_start_illegal", "spaces not ok", + "-dash-.start_illegal", "new.table with space", "01 .table", "ns:-illegaldash", + "new:.illegaldot", "new:illegalcolon1:", "new:illegalcolon1:2"}; + + + @Test(expected = IllegalArgumentException.class) + public void testInvalidNamespace() { + for (String tn : invalidNamespace) { + TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(tn)); + fail("invalid namespace " + tn + " should have failed with IllegalArgumentException for namespace"); + } + } + + @Test(expected = IllegalArgumentException.class) + public void testEmptyTableName() { + for (String tn : emptyTableNames) { + TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(tn)); + fail("invalid tablename " + tn + " should have failed with IllegalArgumentException"); + } + } + + @Test + public void testLegalHTableNames() { + for (String tn : legalTableNames) { + TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(tn)); + } + } + + @Test + public void testIllegalHTableNames() { + for (String tn : illegalTableNames) { + try { + TableName.isLegalFullyQualifiedTableName(Bytes.toBytes(tn)); + fail("invalid tablename " + tn + " should have failed"); + } catch (Exception e) { + // expected + } + } + } + }