From 29f240ac790edb1f13417f5b6064233b15cc9c8c Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Fri, 4 Mar 2022 03:30:29 -0800 Subject: [bun.js] Add `atob` and `btoa` --- src/javascript/jsc/bindings/ZigGlobalObject.cpp | 81 ++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 2 deletions(-) (limited to 'src/javascript/jsc/bindings/ZigGlobalObject.cpp') diff --git a/src/javascript/jsc/bindings/ZigGlobalObject.cpp b/src/javascript/jsc/bindings/ZigGlobalObject.cpp index a3ec63516..6c2847596 100644 --- a/src/javascript/jsc/bindings/ZigGlobalObject.cpp +++ b/src/javascript/jsc/bindings/ZigGlobalObject.cpp @@ -65,7 +65,7 @@ #include #include #include - +#include // #include #include #include @@ -455,13 +455,76 @@ static JSC_DEFINE_HOST_FUNCTION(functionClearTimeout, return Bun__Timer__clearTimeout(globalObject, JSC::JSValue::encode(num)); } +static JSC_DECLARE_HOST_FUNCTION(functionBTOA); + +static JSC_DEFINE_HOST_FUNCTION(functionBTOA, + (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) +{ + JSC::VM& vm = globalObject->vm(); + + if (callFrame->argumentCount() == 0) { + auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); + JSC::throwTypeError(globalObject, scope, "btoa requires 1 argument (a string)"_s); + return JSC::JSValue::encode(JSC::JSValue {}); + } + + const String& stringToEncode = callFrame->argument(0).toWTFString(globalObject); + + if (!stringToEncode || stringToEncode.isNull()) { + return JSC::JSValue::encode(JSC::jsString(vm, WTF::String())); + } + + if (!stringToEncode.isAllLatin1()) { + auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); + // TODO: DOMException + JSC::throwTypeError(globalObject, scope, "The string contains invalid characters."_s); + return JSC::JSValue::encode(JSC::JSValue {}); + } + + return JSC::JSValue::encode(JSC::jsString(vm, WTF::base64EncodeToString(stringToEncode.latin1()))); +} + +static JSC_DECLARE_HOST_FUNCTION(functionATOB); + +static JSC_DEFINE_HOST_FUNCTION(functionATOB, + (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) +{ + JSC::VM& vm = globalObject->vm(); + + if (callFrame->argumentCount() == 0) { + auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); + JSC::throwTypeError(globalObject, scope, "atob requires 1 argument (a string)"_s); + return JSC::JSValue::encode(JSC::JSValue {}); + } + + const WTF::String& encodedString = callFrame->argument(0).toWTFString(globalObject); + + if (encodedString.isNull()) { + return JSC::JSValue::encode(JSC::jsString(vm, "")); + } + + auto decodedData = WTF::base64Decode(encodedString, { + WTF::Base64DecodeOptions::ValidatePadding, + WTF::Base64DecodeOptions::IgnoreSpacesAndNewLines, + WTF::Base64DecodeOptions::DiscardVerticalTab, + }); + if (!decodedData) { + auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); + // TODO: DOMException + JSC::throwTypeError(globalObject, scope, "The string contains invalid characters."_s); + return JSC::JSValue::encode(JSC::JSValue {}); + } + + return JSC::JSValue::encode(JSC::jsString(vm, WTF::String(decodedData->data(), decodedData->size()))); +} + // This is not a publicly exposed API currently. // This is used by the bundler to make Response, Request, FetchEvent, // and any other objects available globally. void GlobalObject::installAPIGlobals(JSClassRef* globals, int count) { WTF::Vector extraStaticGlobals; - extraStaticGlobals.reserveCapacity((size_t)count + 3 + 4); + extraStaticGlobals.reserveCapacity((size_t)count + 3 + 7); int i = 0; for (; i < count - 1; i++) { @@ -531,6 +594,20 @@ void GlobalObject::installAPIGlobals(JSClassRef* globals, int count) "clearInterval", functionClearInterval), JSC::PropertyAttribute::DontDelete | 0 }); + JSC::Identifier atobIdentifier = JSC::Identifier::fromString(vm(), "atob"_s); + extraStaticGlobals.uncheckedAppend( + GlobalPropertyInfo { atobIdentifier, + JSC::JSFunction::create(vm(), JSC::jsCast(this), 0, + "atob", functionATOB), + JSC::PropertyAttribute::DontDelete | 0 }); + + JSC::Identifier btoaIdentifier = JSC::Identifier::fromString(vm(), "btoa"_s); + extraStaticGlobals.uncheckedAppend( + GlobalPropertyInfo { btoaIdentifier, + JSC::JSFunction::create(vm(), JSC::jsCast(this), 0, + "btoa", functionBTOA), + JSC::PropertyAttribute::DontDelete | 0 }); + auto clientData = Bun::clientData(vm()); this->addStaticGlobals(extraStaticGlobals.data(), extraStaticGlobals.size()); -- cgit v1.2.3 tion> Unnamed repository; edit this file 'description' to name the repository.
aboutsummaryrefslogtreecommitdiff
AgeCommit message (Expand)AuthorFilesLines
2022-06-28Fix Tailwind integration Typescript warning (#3732)Gravatar Victor 2-1/+6
2022-06-27[ci] formatGravatar bholmesdev 2-3/+3
2022-06-27Refactor: remove Deno shim to esbuild "banner" (#3734)Gravatar Ben Holmes 7-15/+22
2022-06-27[ci] formatGravatar FredKSchott 9-23/+25
2022-06-27update telemetry to support more anonymized project id (#3713)Gravatar Fred K. Schott 20-351/+311
2022-06-27SImplify "astro add" by removing confusing multi-select (#3715)Gravatar Fred K. Schott 13-258/+157