Fix write buffer overflow by 1 in domain_to_punycode()

This issue has been triggered after the previous commit increased
the size of label_buf.

It has been found by OSS-Fuzz (issue 39226).
The testcase is included into the unit tests.
This commit is contained in:
Tim Rühsen 2021-09-26 18:01:59 +02:00
parent 304ca77522
commit b2625f93f2
2 changed files with 232 additions and 4 deletions

View File

@ -0,0 +1,231 @@
^^Z^^^^^^^^^^^^^^^^^^^^rRRRINS===
com
蟹侔
<EFBFBD>


<EFBFBD>

诟习
习愿
<EFBFBD>
盏7氕<EFBFBD>
诟习
<EFBFBD>
逊佾

诟习888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
証^^^^^^^^^^^^^^^^^^<5E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>^^^^^^^^m^^^^N^<5E>
习愿
一一
懈馗
习愿
<EFBFBD>

侔愿
侏佾

诟习
习愿
<EFBFBD>
<EFBFBD>


<EFBFBD>
缀M泄

诟习
习愿
<EFBFBD>

诟习
<EFBFBD>

诟习
习愿
蟐^a^^^N^^^<5E>
裗^^^^^^穅
^^^<5E>

View File

@ -571,13 +571,11 @@ static int domain_to_punycode(const char *domain, char *out, size_t outsize)
for (e = label = domain; e; label = e + 1) { for (e = label = domain; e; label = e + 1) {
e = strchr(label, '.'); e = strchr(label, '.');
labellen = e ? (size_t) (e - label) : strlen(label); labellen = e ? (size_t) (e - label) : strlen(label);
/* printf("s=%s inlen=%zd\n", label, labellen); */
if (mem_is_ascii(label, labellen)) { if (mem_is_ascii(label, labellen)) {
if (outlen + labellen + (e != NULL) >= outsize) if (outlen + labellen + (e != NULL) >= outsize)
return 1; return 1;
/* printf("outlen=%zd labellen=%zd\n", outlen, labellen); */
memcpy(out + outlen, label, labellen); memcpy(out + outlen, label, labellen);
outlen += labellen; outlen += labellen;
} else { } else {
@ -592,8 +590,7 @@ static int domain_to_punycode(const char *domain, char *out, size_t outsize)
memcpy(out + outlen, "xn--", 4); memcpy(out + outlen, "xn--", 4);
outlen += 4; outlen += 4;
labellen = outsize - outlen; labellen = outsize - outlen - 1; // -1 to leave space for the trailing \0
/* printf("n=%zd space_left=%zd\n", n, labellen); */
if (punycode_encode(inputlen, input, &labellen, out + outlen)) if (punycode_encode(inputlen, input, &labellen, out + outlen))
return 1; return 1;
outlen += labellen; outlen += labellen;