COMMON: Always return the original string on failed punycode decoding

This commit is contained in:
Eugene Sandulenko 2021-07-24 10:34:49 +02:00
parent a655cff203
commit 191bc979a9
No known key found for this signature in database
GPG Key ID: 014D387312D34F08
2 changed files with 21 additions and 11 deletions

View File

@ -21,6 +21,7 @@
*/
#include "common/system.h"
#include "common/punycode.h"
#include "common/textconsole.h"
#include "backends/fs/abstract-fs.h"
#include "backends/fs/fs-factory.h"
@ -290,6 +291,9 @@ void FSDirectory::cacheDirectoryRecursive(FSNode node, int depth, const String&
String lowercaseName = name;
lowercaseName.toLowercase();
// We transparently decode any punycode-named files
lowercaseName = punycode_decodefilename(lowercaseName);
// since the hashmap is case insensitive, we need to check for clashes when caching
if (it->isDirectory()) {
if (!_flat && _subDirCache.contains(lowercaseName)) {

View File

@ -43,6 +43,7 @@
*/
#include "common/punycode.h"
#include "common/debug.h"
#include "common/util.h"
namespace Common {
@ -211,12 +212,11 @@ String punycode_decode(const String src1) {
String src(&src1.c_str()[4]); // Skip the prefix for simplification
int srclen = src.size();
String dst;
/* Ensure that the input contains only ASCII characters. */
for (int si = 0; si < srclen; si++) {
if (src[si] & 0x80) {
return dst;
return src1;
}
}
@ -225,6 +225,8 @@ String punycode_decode(const String src1) {
if (di == String::npos)
return src;
String dst;
for (int i = 0; i < di; i++) {
dst += src[i];
}
@ -241,13 +243,14 @@ String punycode_decode(const String src1) {
int digit = decode_digit(src[si++]);
if (digit == SIZE_MAX) {
goto fail;
warning("punycode_decode: incorrect digit");
return src1;
}
if (digit > (SIZE_MAX - i) / w) {
/* OVERFLOW */
assert(0 && "OVERFLOW");
goto fail;
warning("punycode_decode: overflow1");
return src1;
}
i += digit * w;
@ -267,8 +270,8 @@ String punycode_decode(const String src1) {
if (w > SIZE_MAX / (BASE - t)) {
/* OVERFLOW */
assert(0 && "OVERFLOW");
goto fail;
warning("punycode_decode: overflow2");
return src1;
}
w *= BASE - t;
@ -278,8 +281,8 @@ String punycode_decode(const String src1) {
if (i / (di + 1) > SIZE_MAX - n) {
/* OVERFLOW */
assert(0 && "OVERFLOW");
goto fail;
warning("punycode_decode: overflow3");
return src1;
}
n += i / (di + 1);
@ -292,8 +295,6 @@ String punycode_decode(const String src1) {
i++;
}
fail:
return dst;
}
@ -301,6 +302,11 @@ String punycode_decodefilename(const String src1) {
String dst;
String src = punycode_decode(src1);
// Check if the string did not change which could be
// also on decoding failure
if (src == src1)
return src;
for (int i = 0; i < src.size(); i++) {
if ((byte)src[i] == 0x81 && i + 1 < src.size()) {
i++;