From bc23d108c849c857cab4b3d5caee89ce48757a96 Mon Sep 17 00:00:00 2001 From: sapics Date: Tue, 16 Jun 2020 19:25:39 +0900 Subject: [PATCH] src: fix ParseEncoding "utf-16LE" was parsed "UNKNOWN", this fixes to "UCS2" "utf-buffer" was parsed "BUFFER", this fixes to "UNKNOWN" "utf-16leNOT" was parsed "UCS2", this fixes to "UNKNOWN" PR-URL: https://github.com/nodejs/node/pull/33957 Reviewed-By: Anna Henningsen Reviewed-By: James M Snell --- src/api/encoding.cc | 99 +++++++++++++++++------------- src/util-inl.h | 10 ++- test/addons/parse-encoding/test.js | 3 + 3 files changed, 65 insertions(+), 47 deletions(-) diff --git a/src/api/encoding.cc b/src/api/encoding.cc index fa872f8b76cd31..6df4a7faf30393 100644 --- a/src/api/encoding.cc +++ b/src/api/encoding.cc @@ -14,74 +14,91 @@ enum encoding ParseEncoding(const char* encoding, enum encoding default_encoding) { switch (encoding[0]) { case 'u': + case 'U': // utf8, utf16le if (encoding[1] == 't' && encoding[2] == 'f') { // Skip `-` - encoding += encoding[3] == '-' ? 4 : 3; - if (encoding[0] == '8' && encoding[1] == '\0') + const size_t skip = encoding[3] == '-' ? 4 : 3; + if (encoding[skip] == '8' && encoding[skip + 1] == '\0') return UTF8; - if (strncmp(encoding, "16le", 4) == 0) + if (strncmp(encoding + skip, "16le", 5) == 0) return UCS2; - // ucs2 } else if (encoding[1] == 'c' && encoding[2] == 's') { - encoding += encoding[3] == '-' ? 4 : 3; - if (encoding[0] == '2' && encoding[1] == '\0') + const size_t skip = encoding[3] == '-' ? 4 : 3; + if (encoding[skip] == '2' && encoding[skip + 1] == '\0') return UCS2; } + if (StringEqualNoCase(encoding, "utf8")) + return UTF8; + if (StringEqualNoCase(encoding, "utf-8")) + return UTF8; + if (StringEqualNoCase(encoding, "ucs2")) + return UCS2; + if (StringEqualNoCase(encoding, "ucs-2")) + return UCS2; + if (StringEqualNoCase(encoding, "utf16le")) + return UCS2; + if (StringEqualNoCase(encoding, "utf-16le")) + return UCS2; break; + case 'l': + case 'L': // latin1 if (encoding[1] == 'a') { - if (strncmp(encoding + 2, "tin1", 4) == 0) + if (strncmp(encoding + 2, "tin1", 5) == 0) return LATIN1; } + if (StringEqualNoCase(encoding, "latin1")) + return LATIN1; break; + case 'b': - // binary + case 'B': + // binary is a deprecated alias of latin1 if (encoding[1] == 'i') { - if (strncmp(encoding + 2, "nary", 4) == 0) + if (strncmp(encoding + 2, "nary", 5) == 0) return LATIN1; - // buffer } else if (encoding[1] == 'u') { - if (strncmp(encoding + 2, "ffer", 4) == 0) + if (strncmp(encoding + 2, "ffer", 5) == 0) return BUFFER; + // base64 + } else if (encoding[1] == 'a') { + if (strncmp(encoding + 2, "se64", 5) == 0) + return BASE64; } + if (StringEqualNoCase(encoding, "binary")) + return LATIN1; // BINARY is a deprecated alias of LATIN1. + if (StringEqualNoCase(encoding, "buffer")) + return BUFFER; + if (StringEqualNoCase(encoding, "base64")) + return BASE64; break; - case '\0': - return default_encoding; - default: + + case 'a': + case 'A': + // ascii + if (encoding[1] == 's') { + if (strncmp(encoding + 2, "cii", 4) == 0) + return ASCII; + } + if (StringEqualNoCase(encoding, "ascii")) + return ASCII; break; - } - if (StringEqualNoCase(encoding, "utf8")) { - return UTF8; - } else if (StringEqualNoCase(encoding, "utf-8")) { - return UTF8; - } else if (StringEqualNoCase(encoding, "ascii")) { - return ASCII; - } else if (StringEqualNoCase(encoding, "base64")) { - return BASE64; - } else if (StringEqualNoCase(encoding, "ucs2")) { - return UCS2; - } else if (StringEqualNoCase(encoding, "ucs-2")) { - return UCS2; - } else if (StringEqualNoCase(encoding, "utf16le")) { - return UCS2; - } else if (StringEqualNoCase(encoding, "utf-16le")) { - return UCS2; - } else if (StringEqualNoCase(encoding, "latin1")) { - return LATIN1; - } else if (StringEqualNoCase(encoding, "binary")) { - return LATIN1; // BINARY is a deprecated alias of LATIN1. - } else if (StringEqualNoCase(encoding, "buffer")) { - return BUFFER; - } else if (StringEqualNoCase(encoding, "hex")) { - return HEX; - } else { - return default_encoding; + case 'h': + case 'H': + // hex + if (encoding[1] == 'e') + if (encoding[2] == 'x' && encoding[3] == '\0') + return HEX; + if (StringEqualNoCase(encoding, "hex")) + return HEX; + break; } + return default_encoding; } diff --git a/src/util-inl.h b/src/util-inl.h index 5276fbef07f244..00a9f836e46a40 100644 --- a/src/util-inl.h +++ b/src/util-inl.h @@ -296,12 +296,10 @@ std::string ToUpper(const std::string& in) { } bool StringEqualNoCase(const char* a, const char* b) { - do { - if (*a == '\0') - return *b == '\0'; - if (*b == '\0') - return false; - } while (ToLower(*a++) == ToLower(*b++)); + while (ToLower(*a) == ToLower(*b++)) { + if (*a++ == '\0') + return true; + } return false; } diff --git a/test/addons/parse-encoding/test.js b/test/addons/parse-encoding/test.js index 412346650fa217..1456115a926f3e 100644 --- a/test/addons/parse-encoding/test.js +++ b/test/addons/parse-encoding/test.js @@ -14,6 +14,9 @@ assert.strictEqual(parseEncoding('hex'), 'HEX'); assert.strictEqual(parseEncoding('latin1'), 'LATIN1'); assert.strictEqual(parseEncoding('ucs2'), 'UCS2'); assert.strictEqual(parseEncoding('utf8'), 'UTF8'); +assert.strictEqual(parseEncoding('utf-16LE'), 'UCS2'); +assert.strictEqual(parseEncoding('utf-buffer'), 'UNKNOWN'); +assert.strictEqual(parseEncoding('utf-16leNOT'), 'UNKNOWN'); assert.strictEqual(parseEncoding('linary'), 'UNKNOWN'); assert.strictEqual(parseEncoding('luffer'), 'UNKNOWN');