diff --git a/maldoca/js/ir/analyses/dynamic_constant_propagation/analysis.cc b/maldoca/js/ir/analyses/dynamic_constant_propagation/analysis.cc index 904adb4..4ad3c58 100644 --- a/maldoca/js/ir/analyses/dynamic_constant_propagation/analysis.cc +++ b/maldoca/js/ir/analyses/dynamic_constant_propagation/analysis.cc @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/GraphTraits.h" @@ -174,10 +176,60 @@ std::optional BuiltinBtoa( return mlir::StringAttr::get(context, ascii_string); } +std::set kEncodeURIComponentReservedChars = { + "-", "_", ".", "!", "~", "*", "'", "(", ")", "*", ",", ";", ":", "@", "&", "=", "+", "$", "/", "?", "#" +}; + +std::optional BuiltinDecodeURIComponent( + mlir::MLIRContext *context, absl::Span args) { + if (args.size() != 1) { + return std::nullopt; + } + std::string encoded_str = + llvm::dyn_cast(args[0]).strref().str(); + + std::string decoded; + char hex_char; + for (size_t i = 0; i < encoded_str.length(); ++i) { + if (encoded_str[i] == '%' && i + 2 < encoded_str.length()) { + std::string hex_str = encoded_str.substr(i + 1, 2); + char decoded_char = static_cast(std::stoi(hex_str, nullptr, 16)); + decoded += decoded_char; + i += 2; + } else { + decoded += encoded_str[i]; + } + } + return mlir::StringAttr::get(context, decoded); +} + +std::optional BuiltinEncodeURIComponent( + mlir::MLIRContext *context, absl::Span args) { + if (args.size() != 1) { + return std::nullopt; + } + std::string str = + llvm::dyn_cast(args[0]).strref().str(); + + std::string encoded; + for (char c : str) { + if (isalnum(c) || kEncodeURIComponentReservedChars.count(std::string(1, c))) { + encoded += c; + } else { + encoded += absl::StrFormat("%%%02X", static_cast(c)); + } + } + return mlir::StringAttr::get(context, encoded); +} + + + static const auto *kBuiltins = new absl::flat_hash_map{ {"atob", &BuiltinAtob}, {"btoa", &BuiltinBtoa}, + {"decodeURIComponent", &BuiltinDecodeURIComponent}, + {"encodeURIComponent", &BuiltinEncodeURIComponent}, }; static std::string InlineExprToString(mlir::Attribute expr, size_t indent = 0) { diff --git a/maldoca/js/ir/jsir_gen_lib.h b/maldoca/js/ir/jsir_gen_lib.h index f4f9852..0eedd7b 100644 --- a/maldoca/js/ir/jsir_gen_lib.h +++ b/maldoca/js/ir/jsir_gen_lib.h @@ -48,7 +48,7 @@ enum class JsirPassKind { kEraseComments, kExtractPrelude, kRemoveDirectives, - kNormalizeMemberExpressions, + // kNormalizeMemberExpressions, }; // Analyzes and transforms the provided source code. It first translates the