COMMON: Fix punycode encoding

This commit is contained in:
Eugene Sandulenko 2021-07-25 17:07:18 +02:00
parent 81b7702722
commit cd3f703988
No known key found for this signature in database
GPG key ID: 014D387312D34F08

View file

@ -56,6 +56,7 @@ namespace Common {
#define DAMP 700 #define DAMP 700
#define INITIAL_N 128 #define INITIAL_N 128
#define INITIAL_BIAS 72 #define INITIAL_BIAS 72
#define SMAX 0x7fff
static uint32_t adapt_bias(uint32_t delta, unsigned n_points, int is_first) { static uint32_t adapt_bias(uint32_t delta, unsigned n_points, int is_first) {
uint32_t k; uint32_t k;
@ -122,27 +123,26 @@ static size_t decode_digit(uint32_t v) {
if (Common::isUpper(v)) { if (Common::isUpper(v)) {
return v - 'A'; return v - 'A';
} }
return SIZE_MAX; return SMAX;
} }
String punycode_encode(String src) { String punycode_encode(String src) {
int srclen = src.size(); int srclen = src.size();
int di = 0, si; int h = 0, si;
String dst; String dst;
for (si = 0; si < srclen; si++) { for (si = 0; si < srclen; si++) {
if ((byte)src[si] < 128) { if ((byte)src[si] < 128) {
dst += src[si]; dst += src[si];
di++; h++;
} }
} }
int b = di, h = di; int b = h;
/* Write out delimiter if any basic code points were processed. */ /* Write out delimiter if any basic code points were processed. */
if (di > 0) { if (!dst.empty()) {
dst += '-'; dst += '-';
di++;
} }
int n = INITIAL_N; int n = INITIAL_N;
@ -152,30 +152,29 @@ String punycode_encode(String src) {
for (; h < srclen; n++, delta++) { for (; h < srclen; n++, delta++) {
/* Find next smallest non-basic code point. */ /* Find next smallest non-basic code point. */
for (m = SIZE_MAX, si = 0; si < srclen; si++) { for (m = SMAX, si = 0; si < srclen; si++) {
if (src[si] >= n && src[si] < m) { if ((byte)src[si] >= n && (byte)src[si] < m) {
m = src[si]; m = (byte)src[si];
} }
} }
if ((m - n) > (SIZE_MAX - delta) / (h + 1)) { if ((m - n) > (SMAX - delta) / (h + 1)) {
/* OVERFLOW */ /* OVERFLOW */
assert(0 && "OVERFLOW"); warning("punycode_encode: overflow1");
goto fail; return src;
} }
delta += (m - n) * (h + 1); delta += (m - n) * (h + 1);
n = m; n = m;
for (si = 0; si < srclen; si++) { for (si = 0; si < srclen; si++) {
if (src[si] < n) { if ((byte)src[si] < n) {
if (++delta == 0) { if (++delta == 0) {
/* OVERFLOW */ /* OVERFLOW */
assert(0 && "OVERFLOW"); warning("punycode_encode: overflow2");
goto fail; return src;
} }
} } else if ((byte)src[si] == n) {
else if (src[si] == n) {
dst += encode_var_int(bias, delta); dst += encode_var_int(bias, delta);
bias = adapt_bias(delta, h + 1, h == b); bias = adapt_bias(delta, h + 1, h == b);
delta = 0; delta = 0;
@ -184,7 +183,6 @@ String punycode_encode(String src) {
} }
} }
fail:
/* Return how many Unicode code points were converted. */ /* Return how many Unicode code points were converted. */
return dst; return dst;
} }
@ -239,12 +237,12 @@ String punycode_decode(const String src1) {
for (int w = 1, k = BASE; true; k += BASE) { for (int w = 1, k = BASE; true; k += BASE) {
int digit = decode_digit(src[si++]); int digit = decode_digit(src[si++]);
if (digit == SIZE_MAX) { if (digit == SMAX) {
warning("punycode_decode: incorrect digit"); warning("punycode_decode: incorrect digit");
return src1; return src1;
} }
if (digit > (SIZE_MAX - i) / w) { if (digit > (SMAX - i) / w) {
/* OVERFLOW */ /* OVERFLOW */
warning("punycode_decode: overflow1"); warning("punycode_decode: overflow1");
return src1; return src1;
@ -265,7 +263,7 @@ String punycode_decode(const String src1) {
break; break;
} }
if (w > SIZE_MAX / (BASE - t)) { if (w > SMAX / (BASE - t)) {
/* OVERFLOW */ /* OVERFLOW */
warning("punycode_decode: overflow2"); warning("punycode_decode: overflow2");
return src1; return src1;
@ -276,7 +274,7 @@ String punycode_decode(const String src1) {
bias = adapt_bias(i - org_i, di + 1, org_i == 0); bias = adapt_bias(i - org_i, di + 1, org_i == 0);
if (i / (di + 1) > SIZE_MAX - n) { if (i / (di + 1) > SMAX - n) {
/* OVERFLOW */ /* OVERFLOW */
warning("punycode_decode: overflow3"); warning("punycode_decode: overflow3");
return src1; return src1;
@ -310,7 +308,7 @@ String punycode_encodefilename(const String src) {
} }
} }
return dst; return punycode_encode(dst);
} }
String punycode_decodefilename(const String src1) { String punycode_decodefilename(const String src1) {