Changeset 122034 in webkit


Ignore:
Timestamp:
Jul 6, 2012 1:43:20 PM (12 years ago)
Author:
commit-queue@webkit.org
Message:

Add an API to explicitly call a JavaScript function with args.
https://bugs.webkit.org/show_bug.cgi?id=90694

Currently the Blackberry port doesn't expose the JavaScript
engine to 3rd parties so they rely upon executeJavaScript
which can be slower than necessary and unsafe as eval is used.
This new API provides a way to explicitly call a specific
JavaScript function with a list of args preventing the case
where an argument comes from a untrusted source and tries to
escape the arg list to take control of the JavaScript engine.

In the future if the Blackberry port introduces a formal
way to interact with the JavaScript engine this function should
be removed.

PR 149294

Patch by Benjamin C Meyer <bmeyer@rim.com> on 2012-07-06
Reviewed by Unreviewed

  • Api/WebPage.cpp:

(BlackBerry::WebKit::WebPage::executeJavaScriptFunction):
(WebKit):

  • Api/WebPage.h:
Location:
trunk/Source/WebKit/blackberry
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/blackberry/Api/WebPage.cpp

    r121872 r122034  
    158158#include <JavaScriptCore/APICast.h>
    159159#include <JavaScriptCore/JSContextRef.h>
     160#include <JavaScriptCore/JSStringRef.h>
    160161#include <SharedPointer.h>
    161162#include <sys/keycodes.h>
     
    848849    ScriptSourceCode sourceCode(String::fromUTF8(script), KURL());
    849850    return d->executeJavaScriptInIsolatedWorld(sourceCode, returnType, returnValue);
     851}
     852
     853bool WebPage::executeJavaScriptFunction(const std::vector<std::string> &function, const std::vector<std::string> &args, JavaScriptDataType& returnType, WebString& returnValue)
     854{
     855    if (!d->m_mainFrame)
     856        return false;
     857    JSC::Bindings::RootObject* root = d->m_mainFrame->script()->bindingRootObject();
     858    if (!root)
     859        return false;
     860    JSC::ExecState* exec = root->globalObject()->globalExec();
     861    JSGlobalContextRef ctx = toGlobalRef(exec);
     862
     863    WTF::Vector<JSStringRef> argList(args.size());
     864    WTF::Vector<JSValueRef> argListRef(args.size());
     865    for (unsigned i = 0; i < args.size(); ++i) {
     866        JSStringRef str = JSStringCreateWithUTF8CString(args[i].c_str());
     867        argList[i] = str;
     868        JSValueRef strRef = JSValueMakeString(ctx, str);
     869        argListRef[i] = strRef;
     870    }
     871
     872    JSValueRef windowObjectValue = windowObject();
     873    JSObjectRef obj = JSValueToObject(ctx, windowObjectValue, 0);
     874    JSObjectRef thisObject = obj;
     875    for (unsigned i = 0; i < function.size(); ++i) {
     876        JSStringRef str = JSStringCreateWithUTF8CString(function[i].c_str());
     877        thisObject = obj;
     878        obj = JSValueToObject(ctx, JSObjectGetProperty(ctx, obj, str, 0), 0);
     879        JSStringRelease(str);
     880        if (!obj)
     881            break;
     882    }
     883
     884    JSObjectRef functionObject = obj;
     885    JSValueRef result = 0;
     886    JSValueRef exception;
     887    if (functionObject && thisObject)
     888        result = JSObjectCallAsFunction(ctx, functionObject, thisObject, args.size(), argListRef.data(), &exception);
     889
     890    for (unsigned i = 0; i < args.size(); ++i)
     891        JSStringRelease(argList[i]);
     892
     893    JSC::JSValue value = toJS(exec, result);
     894
     895    if (!value) {
     896        returnType = JSException;
     897        JSStringRef stringRef = JSValueToStringCopy(ctx, exception, 0);
     898        size_t bufferSize = JSStringGetMaximumUTF8CStringSize(stringRef);
     899        WTF::Vector<char> buffer(bufferSize);
     900        JSStringGetUTF8CString(stringRef, buffer.data(), bufferSize);
     901        returnValue = WebString::fromUtf8(buffer.data());
     902        return false;
     903    }
     904
     905    JSType type = JSValueGetType(ctx, result);
     906
     907    switch (type) {
     908    case kJSTypeNull:
     909        returnType = JSNull;
     910        break;
     911    case kJSTypeBoolean:
     912        returnType = JSBoolean;
     913        break;
     914    case kJSTypeNumber:
     915        returnType = JSNumber;
     916        break;
     917    case kJSTypeString:
     918        returnType = JSString;
     919        break;
     920    case kJSTypeObject:
     921        returnType = JSObject;
     922        break;
     923    case kJSTypeUndefined:
     924    default:
     925        returnType = JSUndefined;
     926        break;
     927    }
     928
     929    if (returnType == JSBoolean || returnType == JSNumber || returnType == JSString || returnType == JSObject) {
     930        JSStringRef stringRef = JSValueToStringCopy(ctx, result, 0);
     931        size_t bufferSize = JSStringGetMaximumUTF8CStringSize(stringRef);
     932        WTF::Vector<char> buffer(bufferSize);
     933        JSStringGetUTF8CString(stringRef, buffer.data(), bufferSize);
     934        returnValue = WebString::fromUtf8(buffer.data());
     935    }
     936
     937    return true;
    850938}
    851939
  • trunk/Source/WebKit/blackberry/Api/WebPage.h

    r121626 r122034  
    2828#include <imf/input_data.h>
    2929#include <network/NetworkRequest.h>
     30#include <string>
     31#include <vector>
    3032
    3133struct OpaqueJSContext;
     
    103105    // Takes a UTF16 encoded script that is used explicitly by the pattern matching code
    104106    bool executeJavaScriptInIsolatedWorld(const std::wstring& script, JavaScriptDataType& returnType, WebString& returnValue);
     107
     108    bool executeJavaScriptFunction(const std::vector<std::string> &script, const std::vector<std::string> &args, JavaScriptDataType& returnType, WebString& returnValue);
    105109
    106110    void initializeIconDataBase();
  • trunk/Source/WebKit/blackberry/ChangeLog

    r121931 r122034  
     12012-07-06  Benjamin C Meyer  <bmeyer@rim.com>
     2
     3        Add an API to explicitly call a JavaScript function with args.
     4        https://bugs.webkit.org/show_bug.cgi?id=90694
     5
     6        Currently the Blackberry port doesn't expose the JavaScript
     7        engine to 3rd parties so they rely upon executeJavaScript
     8        which can be slower than necessary and unsafe as eval is used.
     9        This new API provides a way to explicitly call a specific
     10        JavaScript function with a list of args preventing the case
     11        where an argument comes from a untrusted source and tries to
     12        escape the arg list to take control of the JavaScript engine.
     13
     14        In the future if the Blackberry port introduces a formal
     15        way to interact with the JavaScript engine this function should
     16        be removed.
     17
     18        PR 149294
     19
     20        Reviewed by Unreviewed
     21
     22        * Api/WebPage.cpp:
     23        (BlackBerry::WebKit::WebPage::executeJavaScriptFunction):
     24        (WebKit):
     25        * Api/WebPage.h:
     26
    1272012-07-05  Charles Wei  <charles.wei@torchmobile.com.cn>
    228
Note: See TracChangeset for help on using the changeset viewer.