Fix the potential copyright issue in SocksCommonUtils
- Add StringUtil.toHexString() methods which are based on LoggingHandler's lookup table implementation, and use it wherever possible
This commit is contained in:
parent
9bee78f91c
commit
c4c71e6d28
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package io.netty.handler.codec.socks;
|
||||
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
final class SocksCommonUtils {
|
||||
public static final SocksRequest UNKNOWN_SOCKS_REQUEST = new UnknownSocksRequest();
|
||||
public static final SocksResponse UNKNOWN_SOCKS_RESPONSE = new UnknownSocksResponse();
|
||||
@ -28,7 +30,7 @@ final class SocksCommonUtils {
|
||||
* A constructor to stop this class being constructed.
|
||||
*/
|
||||
private SocksCommonUtils() {
|
||||
//NOOP
|
||||
// NOOP
|
||||
}
|
||||
|
||||
public static String intToIp(int i) {
|
||||
@ -41,10 +43,10 @@ final class SocksCommonUtils {
|
||||
private static final char[] ipv6conseqZeroFiller = {':', ':'};
|
||||
private static final char ipv6hextetSeparator = ':';
|
||||
|
||||
/*
|
||||
* Convert numeric IPv6 to compressed format, where
|
||||
* the longest sequence of 0's (with 2 or more 0's) is replaced with "::"
|
||||
*/
|
||||
/**
|
||||
* Convert numeric IPv6 to compressed format, where
|
||||
* the longest sequence of 0's (with 2 or more 0's) is replaced with "::"
|
||||
*/
|
||||
public static String ipv6toCompressedForm(byte[] src) {
|
||||
assert src.length == 16;
|
||||
//Find the longest sequence of 0's
|
||||
@ -77,12 +79,9 @@ final class SocksCommonUtils {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert numeric IPv6 to standard (non-compressed) format.
|
||||
*
|
||||
* Borrowed from Inet6Address.java #numericToTextFormat(byte[])
|
||||
* Changed StringBuffer -> StringBuilder and ":" -> ':' for performance.
|
||||
*/
|
||||
/**
|
||||
* Converts numeric IPv6 to standard (non-compressed) format.
|
||||
*/
|
||||
public static String ipv6toStr(byte[] src) {
|
||||
assert src.length == 16;
|
||||
StringBuilder sb = new StringBuilder(39);
|
||||
@ -90,14 +89,18 @@ final class SocksCommonUtils {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static void ipv6toStr(StringBuilder sb, byte[] src,
|
||||
int fromHextet, int toHextet) {
|
||||
for (int i = fromHextet; i < toHextet; i++) {
|
||||
sb.append(Integer.toHexString(src[i << 1] << 8 & 0xff00
|
||||
| src[(i << 1) + 1] & 0xff));
|
||||
if (i < toHextet - 1) {
|
||||
sb.append(ipv6hextetSeparator);
|
||||
}
|
||||
private static void ipv6toStr(StringBuilder sb, byte[] src, int fromHextet, int toHextet) {
|
||||
int i;
|
||||
toHextet --;
|
||||
for (i = fromHextet; i < toHextet; i++) {
|
||||
appendHextet(sb, src, i);
|
||||
sb.append(ipv6hextetSeparator);
|
||||
}
|
||||
|
||||
appendHextet(sb, src, i);
|
||||
}
|
||||
|
||||
private static void appendHextet(StringBuilder sb, byte[] src, int i) {
|
||||
StringUtil.toHexString(sb, src, i << 1, 2);
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +77,8 @@ public class SocksCmdResponseDecoderTest {
|
||||
"testDomain.com", 80);
|
||||
testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, SocksAddressType.IPv6,
|
||||
"2001:db8:85a3:42:1000:8a2e:370:7334", 80);
|
||||
testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, SocksAddressType.IPv6,
|
||||
"1111:111:11:1:0:0:0:1", 80);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package io.netty.util.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Formatter;
|
||||
import java.util.List;
|
||||
@ -24,13 +25,14 @@ import java.util.List;
|
||||
*/
|
||||
public final class StringUtil {
|
||||
|
||||
private StringUtil() {
|
||||
// Unused.
|
||||
}
|
||||
|
||||
public static final String NEWLINE;
|
||||
|
||||
private static final String[] BYTE2HEX_PAD = new String[256];
|
||||
private static final String[] BYTE2HEX_NOPAD = new String[256];
|
||||
private static final String EMPTY_STRING = "";
|
||||
|
||||
static {
|
||||
// Determine the newline character of the current platform.
|
||||
String newLine;
|
||||
|
||||
try {
|
||||
@ -41,9 +43,32 @@ public final class StringUtil {
|
||||
}
|
||||
|
||||
NEWLINE = newLine;
|
||||
}
|
||||
|
||||
private static final String EMPTY_STRING = "";
|
||||
// Generate the lookup table that converts a byte into a 2-digit hexadecimal integer.
|
||||
int i;
|
||||
for (i = 0; i < 10; i ++) {
|
||||
StringBuilder buf = new StringBuilder(2);
|
||||
buf.append('0');
|
||||
buf.append(i);
|
||||
BYTE2HEX_PAD[i] = buf.toString();
|
||||
BYTE2HEX_NOPAD[i] = String.valueOf(i);
|
||||
}
|
||||
for (; i < 16; i ++) {
|
||||
StringBuilder buf = new StringBuilder(2);
|
||||
char c = (char) ('a' + i - 10);
|
||||
buf.append('0');
|
||||
buf.append(c);
|
||||
BYTE2HEX_PAD[i] = buf.toString();
|
||||
BYTE2HEX_NOPAD[i] = String.valueOf(c);
|
||||
}
|
||||
for (; i < BYTE2HEX_PAD.length; i ++) {
|
||||
StringBuilder buf = new StringBuilder(2);
|
||||
buf.append(Integer.toHexString(i));
|
||||
String str = buf.toString();
|
||||
BYTE2HEX_PAD[i] = str;
|
||||
BYTE2HEX_NOPAD[i] = str;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits the specified {@link String} with the specified delimiter. This operation is a simplified and optimized
|
||||
@ -86,6 +111,124 @@ public final class StringUtil {
|
||||
return res.toArray(new String[res.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the specified byte value into a 2-digit hexadecimal integer.
|
||||
*/
|
||||
public static String byteToHexStringPadded(int value) {
|
||||
return BYTE2HEX_PAD[value & 0xff];
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the specified byte value into a 2-digit hexadecimal integer and appends it to the specified buffer.
|
||||
*/
|
||||
public static <T extends Appendable> T byteToHexStringPadded(T buf, int value) {
|
||||
try {
|
||||
buf.append(byteToHexStringPadded(value));
|
||||
} catch (IOException e) {
|
||||
PlatformDependent.throwException(e);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the specified byte array into a hexadecimal value.
|
||||
*/
|
||||
public static String toHexStringPadded(byte[] src) {
|
||||
return toHexStringPadded(src, 0, src.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the specified byte array into a hexadecimal value.
|
||||
*/
|
||||
public static String toHexStringPadded(byte[] src, int offset, int length) {
|
||||
return toHexStringPadded(new StringBuilder(length << 1), src, offset, length).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the specified byte array into a hexadecimal value and appends it to the specified buffer.
|
||||
*/
|
||||
public static <T extends Appendable> T toHexStringPadded(T dst, byte[] src) {
|
||||
return toHexStringPadded(dst, src, 0, src.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the specified byte array into a hexadecimal value and appends it to the specified buffer.
|
||||
*/
|
||||
public static <T extends Appendable> T toHexStringPadded(T dst, byte[] src, int offset, int length) {
|
||||
final int end = offset + length;
|
||||
for (int i = offset; i < end; i ++) {
|
||||
byteToHexStringPadded(dst, src[i]);
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the specified byte value into a hexadecimal integer.
|
||||
*/
|
||||
public static String byteToHexString(int value) {
|
||||
return BYTE2HEX_NOPAD[value & 0xff];
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the specified byte value into a hexadecimal integer and appends it to the specified buffer.
|
||||
*/
|
||||
public static <T extends Appendable> T byteToHexString(T buf, int value) {
|
||||
try {
|
||||
buf.append(byteToHexString(value));
|
||||
} catch (IOException e) {
|
||||
PlatformDependent.throwException(e);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the specified byte array into a hexadecimal value.
|
||||
*/
|
||||
public static String toHexString(byte[] src) {
|
||||
return toHexString(src, 0, src.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the specified byte array into a hexadecimal value.
|
||||
*/
|
||||
public static String toHexString(byte[] src, int offset, int length) {
|
||||
return toHexString(new StringBuilder(length << 1), src, offset, length).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the specified byte array into a hexadecimal value and appends it to the specified buffer.
|
||||
*/
|
||||
public static <T extends Appendable> T toHexString(T dst, byte[] src) {
|
||||
return toHexString(dst, src, 0, src.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the specified byte array into a hexadecimal value and appends it to the specified buffer.
|
||||
*/
|
||||
public static <T extends Appendable> T toHexString(T dst, byte[] src, int offset, int length) {
|
||||
assert length >= 0;
|
||||
if (length == 0) {
|
||||
return dst;
|
||||
}
|
||||
|
||||
final int end = offset + length;
|
||||
final int endMinusOne = end - 1;
|
||||
int i;
|
||||
|
||||
// Skip preceding zeroes.
|
||||
for (i = offset; i < endMinusOne; i ++) {
|
||||
if (src[i] != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
byteToHexString(dst, src[i ++]);
|
||||
int remaining = end - i;
|
||||
toHexStringPadded(dst, src, i, remaining);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* The shortcut to {@link #simpleClassName(Class) simpleClassName(o.getClass())}.
|
||||
*/
|
||||
@ -113,4 +256,8 @@ public final class StringUtil {
|
||||
return clazz.getName();
|
||||
}
|
||||
}
|
||||
|
||||
private StringUtil() {
|
||||
// Unused.
|
||||
}
|
||||
}
|
||||
|
@ -17,37 +17,57 @@ package io.netty.util.internal;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static io.netty.util.internal.StringUtil.*;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class StringUtilTest {
|
||||
|
||||
@Test
|
||||
public void ensureNewlineExists() {
|
||||
assertNotNull(StringUtil.NEWLINE);
|
||||
assertNotNull(NEWLINE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToHexString() {
|
||||
assertThat(toHexString(new byte[] { 0 }), is("0"));
|
||||
assertThat(toHexString(new byte[] { 1 }), is("1"));
|
||||
assertThat(toHexString(new byte[] { 0, 0 }), is("0"));
|
||||
assertThat(toHexString(new byte[] { 1, 0 }), is("100"));
|
||||
assertThat(toHexString(EmptyArrays.EMPTY_BYTES), is(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToHexStringPadded() {
|
||||
assertThat(toHexStringPadded(new byte[]{0}), is("00"));
|
||||
assertThat(toHexStringPadded(new byte[]{1}), is("01"));
|
||||
assertThat(toHexStringPadded(new byte[]{0, 0}), is("0000"));
|
||||
assertThat(toHexStringPadded(new byte[]{1, 0}), is("0100"));
|
||||
assertThat(toHexStringPadded(EmptyArrays.EMPTY_BYTES), is(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void splitSimple() {
|
||||
assertArrayEquals(new String[] { "foo", "bar" }, StringUtil.split("foo:bar", ':'));
|
||||
assertArrayEquals(new String[] { "foo", "bar" }, split("foo:bar", ':'));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void splitWithTrailingDelimiter() {
|
||||
assertArrayEquals(new String[] { "foo", "bar" }, StringUtil.split("foo,bar,", ','));
|
||||
assertArrayEquals(new String[] { "foo", "bar" }, split("foo,bar,", ','));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void splitWithTrailingDelimiters() {
|
||||
assertArrayEquals(new String[] { "foo", "bar" }, StringUtil.split("foo!bar!!", '!'));
|
||||
assertArrayEquals(new String[] { "foo", "bar" }, split("foo!bar!!", '!'));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void splitWithConsecutiveDelimiters() {
|
||||
assertArrayEquals(new String[] { "foo", "", "bar" }, StringUtil.split("foo$$bar", '$'));
|
||||
assertArrayEquals(new String[] { "foo", "", "bar" }, split("foo$$bar", '$'));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void splitWithDelimiterAtBeginning() {
|
||||
assertArrayEquals(new String[] { "", "foo", "bar" }, StringUtil.split("#foo#bar", '#'));
|
||||
assertArrayEquals(new String[] { "", "foo", "bar" }, split("#foo#bar", '#'));
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandler.Sharable;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import io.netty.util.internal.logging.InternalLogLevel;
|
||||
import io.netty.util.internal.logging.InternalLogger;
|
||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||
@ -48,23 +49,8 @@ public class LoggingHandler extends ChannelDuplexHandler {
|
||||
int i;
|
||||
|
||||
// Generate the lookup table for byte-to-hex-dump conversion
|
||||
for (i = 0; i < 10; i ++) {
|
||||
StringBuilder buf = new StringBuilder(3);
|
||||
buf.append(" 0");
|
||||
buf.append(i);
|
||||
BYTE2HEX[i] = buf.toString();
|
||||
}
|
||||
for (; i < 16; i ++) {
|
||||
StringBuilder buf = new StringBuilder(3);
|
||||
buf.append(" 0");
|
||||
buf.append((char) ('a' + i - 10));
|
||||
BYTE2HEX[i] = buf.toString();
|
||||
}
|
||||
for (; i < BYTE2HEX.length; i ++) {
|
||||
StringBuilder buf = new StringBuilder(3);
|
||||
buf.append(' ');
|
||||
buf.append(Integer.toHexString(i));
|
||||
BYTE2HEX[i] = buf.toString();
|
||||
for (i = 0; i < BYTE2HEX.length; i ++) {
|
||||
BYTE2HEX[i] = ' ' + StringUtil.byteToHexStringPadded(i);
|
||||
}
|
||||
|
||||
// Generate the lookup table for hex dump paddings
|
||||
|
Loading…
Reference in New Issue
Block a user