IdUtils: Forbid characters that cannot be used in znodes. (#10659)

* IdUtils: Forbid characters that cannot be used in znodes.

* Fix whitespace.
This commit is contained in:
Gian Merlino 2020-12-10 10:49:40 -08:00 committed by GitHub
parent be019760bb
commit 753fa6b3bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 0 deletions

View File

@ -24,6 +24,7 @@ import com.google.common.base.Joiner;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import org.apache.druid.java.util.common.DateTimes; import org.apache.druid.java.util.common.DateTimes;
import org.apache.druid.java.util.common.IAE;
import org.apache.druid.java.util.common.StringUtils; import org.apache.druid.java.util.common.StringUtils;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.joda.time.Interval; import org.joda.time.Interval;
@ -60,6 +61,17 @@ public class IdUtils
!m.matches(), !m.matches(),
StringUtils.format("%s cannot contain whitespace character except space.", thingToValidate) StringUtils.format("%s cannot contain whitespace character except space.", thingToValidate)
); );
for (int i = 0; i < stringToValidate.length(); i++) {
final char c = stringToValidate.charAt(i);
// Curator doesn't permit any of the following ranges, so we can't either, because IDs are often used as
// znode paths. The first two ranges are control characters, the second two ranges correspond to surrogate
// pairs. This means that characters outside the basic multilingual plane, such as emojis, are not allowed. 😢
if (c > 0 && c < 31 || c > 127 && c < 159 || c > '\ud800' && c < '\uf8ff' || c > '\ufff0' && c < '\uffff') {
throw new IAE("%s cannot contain character #%d (at position %d).", thingToValidate, (int) c, i);
}
}
} }
public static String getRandomId() public static String getRandomId()

View File

@ -112,6 +112,22 @@ public class IdUtilsTest
IdUtils.validateId(THINGO, "form\u000cfeed?"); IdUtils.validateId(THINGO, "form\u000cfeed?");
} }
@Test
public void testInvalidUnprintableChars()
{
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("thingToValidate cannot contain character #129 (at position 4).");
IdUtils.validateId(THINGO, "form\u0081feed?");
}
@Test
public void testInvalidEmojis()
{
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("thingToValidate cannot contain character #55357 (at position 4).");
IdUtils.validateId(THINGO, "form💯feed?");
}
@Test @Test
public void testNewTaskIdWithoutInterval() public void testNewTaskIdWithoutInterval()
{ {