Skip to content

Commit

Permalink
[ISSUE 3585] [Part F] eliminate regex match in topic/group name check (
Browse files Browse the repository at this point in the history
  • Loading branch information
shuangchengsun committed Dec 9, 2021
1 parent e2a4b37 commit 50d45f2
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 52 deletions.
52 changes: 13 additions & 39 deletions client/src/main/java/org/apache/rocketmq/client/Validators.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

package org.apache.rocketmq.client;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.apache.rocketmq.common.topic.TopicValidator.isTopicOrGroupIllegal;

import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.UtilAll;
Expand All @@ -30,23 +30,9 @@
* Common Validator
*/
public class Validators {
public static final String VALID_PATTERN_STR = "^[%|a-zA-Z0-9_-]+$";
public static final Pattern PATTERN = Pattern.compile(VALID_PATTERN_STR);
public static final int CHARACTER_MAX_LENGTH = 255;
public static final int TOPIC_MAX_LENGTH = 127;

/**
* @return The resulting {@code String}
*/
public static String getGroupWithRegularExpression(String origin, String patternStr) {
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(origin);
while (matcher.find()) {
return matcher.group(0);
}
return null;
}

/**
* Validate group
*/
Expand All @@ -59,27 +45,15 @@ public static void checkGroup(String group) throws MQClientException {
throw new MQClientException("the specified group is longer than group max length 255.", null);
}

if (!regularExpressionMatcher(group, PATTERN)) {
throw new MQClientException(String.format(
"the specified group[%s] contains illegal characters, allowing only %s", group,
VALID_PATTERN_STR), null);
}

}

/**
* @return <tt>true</tt> if, and only if, the entire origin sequence matches this matcher's pattern
*/
public static boolean regularExpressionMatcher(String origin, Pattern pattern) {
if (pattern == null) {
return true;
if (isTopicOrGroupIllegal(group)) {
throw new MQClientException(String.format(
"the specified group[%s] contains illegal characters, allowing only %s", group,
"^[%|a-zA-Z0-9_-]+$"), null);
}
Matcher matcher = pattern.matcher(origin);
return matcher.matches();
}

public static void checkMessage(Message msg, DefaultMQProducer defaultMQProducer)
throws MQClientException {
public static void checkMessage(Message msg, DefaultMQProducer defaultMQProducer) throws MQClientException {
if (null == msg) {
throw new MQClientException(ResponseCode.MESSAGE_ILLEGAL, "the message is null");
}
Expand Down Expand Up @@ -107,16 +81,16 @@ public static void checkTopic(String topic) throws MQClientException {
throw new MQClientException("The specified topic is blank", null);
}

if (!regularExpressionMatcher(topic, PATTERN)) {
throw new MQClientException(String.format(
"The specified topic[%s] contains illegal characters, allowing only %s", topic,
VALID_PATTERN_STR), null);
}

if (topic.length() > TOPIC_MAX_LENGTH) {
throw new MQClientException(
String.format("The specified topic is longer than topic max length %d.", TOPIC_MAX_LENGTH), null);
}

if (isTopicOrGroupIllegal(topic)) {
throw new MQClientException(String.format(
"The specified topic[%s] contains illegal characters, allowing only %s", topic,
"^[%|a-zA-Z0-9_-]+$"), null);
}
}

public static void isSystemTopic(String topic) throws MQClientException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public void testCheckTopic_HasIllegalCharacters() {
Validators.checkTopic(illegalTopic);
failBecauseExceptionWasNotThrown(MQClientException.class);
} catch (MQClientException e) {
assertThat(e).hasMessageStartingWith(String.format("The specified topic[%s] contains illegal characters, allowing only %s", illegalTopic, Validators.VALID_PATTERN_STR));
assertThat(e).hasMessageStartingWith(String.format("The specified topic[%s] contains illegal characters, allowing only %s", illegalTopic, "^[%|a-zA-Z0-9_-]+$"));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@

import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TopicValidator {

Expand All @@ -38,9 +36,7 @@ public class TopicValidator {
public static final String RMQ_SYS_OFFSET_MOVED_EVENT = "OFFSET_MOVED_EVENT";

public static final String SYSTEM_TOPIC_PREFIX = "rmq_sys_";

private static final String VALID_PATTERN_STR = "^[%|a-zA-Z0-9_-]+$";
private static final Pattern PATTERN = Pattern.compile(VALID_PATTERN_STR);
public static final boolean[] VALID_CHAR_BIT_MAP = new boolean[128];
private static final int TOPIC_MAX_LENGTH = 127;

private static final Set<String> SYSTEM_TOPIC_SET = new HashSet<String>();
Expand All @@ -62,14 +58,41 @@ public class TopicValidator {
SYSTEM_TOPIC_SET.add(RMQ_SYS_OFFSET_MOVED_EVENT);

NOT_ALLOWED_SEND_TOPIC_SET.add(RMQ_SYS_SCHEDULE_TOPIC);

// regex: ^[%|a-zA-Z0-9_-]+$
// %
VALID_CHAR_BIT_MAP['%'] = true;
// -
VALID_CHAR_BIT_MAP['-'] = true;
// _
VALID_CHAR_BIT_MAP['_'] = true;
// |
VALID_CHAR_BIT_MAP['|'] = true;
for (int i = 0; i < VALID_CHAR_BIT_MAP.length; i++) {
if (i >= '0' && i <= '9') {
// 0-9
VALID_CHAR_BIT_MAP[i] = true;
} else if (i >= 'A' && i <= 'Z') {
// A-Z
VALID_CHAR_BIT_MAP[i] = true;
} else if (i >= 'a' && i <= 'z') {
// a-z
VALID_CHAR_BIT_MAP[i] = true;
}
}
}

private static boolean regularExpressionMatcher(String origin, Pattern pattern) {
if (pattern == null) {
return true;
public static boolean isTopicOrGroupIllegal(String str) {
int strLen = str.length();
int len = VALID_CHAR_BIT_MAP.length;
boolean[] bitMap = VALID_CHAR_BIT_MAP;
for (int i = 0; i < strLen; i++) {
char ch = str.charAt(i);
if (ch >= len || !bitMap[ch]) {
return true;
}
}
Matcher matcher = pattern.matcher(origin);
return matcher.matches();
return false;
}

public static boolean validateTopic(String topic, RemotingCommand response) {
Expand All @@ -80,9 +103,9 @@ public static boolean validateTopic(String topic, RemotingCommand response) {
return false;
}

if (!regularExpressionMatcher(topic, PATTERN)) {
if (isTopicOrGroupIllegal(topic)) {
response.setCode(ResponseCode.SYSTEM_ERROR);
response.setRemark("The specified topic contains illegal characters, allowing only " + VALID_PATTERN_STR);
response.setRemark("The specified topic contains illegal characters, allowing only ^[%|a-zA-Z0-9_-]+$");
return false;
}

Expand Down

0 comments on commit 50d45f2

Please sign in to comment.