bool rs::jsapi::Object::Get(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp) { JSAutoRequest ar(cx); auto state = Object::GetState(cx, obj); if (state != nullptr && state->getter != nullptr) { Value value(cx); auto name = JSID_TO_STRING(id); char nameBuffer[256]; auto nameLength = JS_EncodeStringToBuffer(cx, name, nameBuffer, sizeof(nameBuffer) - 1); try { value.setUndefined(); if (nameLength < sizeof(nameBuffer)) { nameBuffer[nameLength] = '\0'; state->getter(nameBuffer, value); } else { std::vector<char> nameVector(nameLength + 1); nameLength = JS_EncodeStringToBuffer(cx, name, &nameVector[0], nameVector.size() - 1); nameVector[nameLength] = '\0'; state->getter(&nameVector[0], value); } vp.set(value); return true; } catch (const std::exception& ex) { JS_ReportError(cx, ex.what()); return false; } } else { vp.setUndefined(); return true; } }
bool rs::jsapi::Object::CallFunction(JSContext* cx, unsigned argc, JS::Value* vp) { JSAutoRequest ar(cx); char nameBuffer[256]; const char* name = nameBuffer; auto args = JS::CallArgsFromVp(argc, vp); auto func = JS_ValueToFunction(cx, args.calleev()); if (func != nullptr) { auto funcName = JS_GetFunctionId(func); if (funcName != nullptr) { auto nameLength = JS_EncodeStringToBuffer(cx, funcName, nameBuffer, sizeof(nameBuffer)); if ((nameLength + 1) < sizeof(nameBuffer)) { nameBuffer[nameLength] = '\0'; } else { std::vector<char> vBuffer(nameLength + 1); JS_EncodeStringToBuffer(cx, funcName, &vBuffer[0], nameLength); vBuffer[nameLength] = '\0'; name = &vBuffer[0]; } } } if (name == nullptr) { // TODO: test this case JS_ReportError(cx, "Unable to find function in libjsapi object"); return false; } else { auto that = args.thisv(); auto state = that.isObjectOrNull() ? Object::GetState(cx, JS::RootedObject(cx, that.toObjectOrNull())) : nullptr; if (state == nullptr) { // TODO: test this case JS_ReportError(cx, "Unable to find function callback in libjsapi object"); return false; } else { try { static thread_local std::vector<Value> vArgs; VectorUtils::ScopedVectorCleaner<Value> clean(vArgs); for (int i = 0; i < argc; ++i) { vArgs.emplace_back(cx, args.get(i)); } Value result(cx); state->functions[name](vArgs, result); args.rval().set(result); return true; } catch (const std::exception& ex) { JS_ReportError(cx, ex.what()); return false; } } } }
rpmRC rpmjsRun(rpmjs js, const char * str, const char ** resultp) { rpmRC rc = RPMRC_FAIL; if (!(str && *str)) goto exit; if (js == NULL) js = rpmjsI(); #if defined(WITH_GPSEE) { gpsee_interpreter_t * I = js->I; jsval v = JSVAL_VOID; JSBool ok = JS_EvaluateScript(I->cx, I->realm->globalObject, str, strlen(str), __FILE__, __LINE__, &v); if (!ok) goto exit; rc = RPMRC_OK; if (resultp && JSVAL_IS_STRING(v)) { JSString * rstr = JSVAL_TO_STRING(v); size_t ns = JS_GetStringEncodingLength(I->cx, rstr); char * s = xmalloc(ns+1); ns = JS_EncodeStringToBuffer(rstr, s, ns); s[ns] = '\0'; *resultp = s; } } #endif /* WITH_GPSEE */ exit: RPMJSDBG(0, (stderr, "<== %s(%p,%p[%u]) rc %d\n", __FUNCTION__, js, str, (unsigned)(str ? strlen(str) : 0), rc)); return rc; }
static JSBool Sys_openlog(JSContext *cx, unsigned argc, jsval *vp) { static char ident[40] = "mailfilter"; size_t len = sizeof(ident) - 1; int32_t facility = LOG_MAIL; if (argc >= 1) { JSString *str = JSVAL_TO_STRING(JS_ARGV(cx, vp)[0]); len = JS_EncodeStringToBuffer(str, ident, len); if (len < 0 || len >= sizeof(ident)) len = sizeof(ident) - 1; ident[len] = '\0'; } if (argc >= 2) JS_ValueToInt32(cx, JS_ARGV(cx, vp)[1], &facility); openlog(ident, LOG_PID, facility); // FIXME for better portability, do not pass vsyslog directly; // instead create a wrapper function that translates priority // from JS_LOG_* to LOG_* JS_LogSetCallback(vsyslog); return JS_TRUE; }
nsresult XPCJSStackFrame::CreateStack(JSContext* cx, JSStackFrame* fp, XPCJSStackFrame** stack) { static const unsigned MAX_FRAMES = 100; unsigned numFrames = 0; nsRefPtr<XPCJSStackFrame> first = new XPCJSStackFrame(); nsRefPtr<XPCJSStackFrame> self = first; while (fp && self) { if (!JS_IsScriptFrame(cx, fp)) { self->mLanguage = nsIProgrammingLanguage::CPLUSPLUS; } else { self->mLanguage = nsIProgrammingLanguage::JAVASCRIPT; JSScript* script = JS_GetFrameScript(cx, fp); jsbytecode* pc = JS_GetFramePC(cx, fp); if (script && pc) { JS::AutoEnterFrameCompartment ac; if (ac.enter(cx, fp)) { const char* filename = JS_GetScriptFilename(cx, script); if (filename) { self->mFilename = (char*) nsMemory::Clone(filename, sizeof(char)*(strlen(filename)+1)); } self->mLineno = (int32_t) JS_PCToLineNumber(cx, script, pc); JSFunction* fun = JS_GetFrameFunction(cx, fp); if (fun) { JSString *funid = JS_GetFunctionId(fun); if (funid) { size_t length = JS_GetStringEncodingLength(cx, funid); if (length != size_t(-1)) { self->mFunname = static_cast<char *>(nsMemory::Alloc(length + 1)); if (self->mFunname) { JS_EncodeStringToBuffer(funid, self->mFunname, length); self->mFunname[length] = '\0'; } } } } } } else { self->mLanguage = nsIProgrammingLanguage::CPLUSPLUS; } } if (++numFrames > MAX_FRAMES) { fp = NULL; } else if (JS_FrameIterator(cx, &fp)) { XPCJSStackFrame* frame = new XPCJSStackFrame(); self->mCaller = frame; self = frame; } } *stack = first.forget().get(); return NS_OK; }
bool ScriptInterface::EnumeratePropertyNamesWithPrefix(JS::HandleValue objVal, const char* prefix, std::vector<std::string>& out) { JSAutoRequest rq(m->m_cx); if (!objVal.isObjectOrNull()) { LOGERROR("EnumeratePropertyNamesWithPrefix expected object type!"); return false; } if(objVal.isNull()) return true; // reached the end of the prototype chain JS::RootedObject obj(m->m_cx, &objVal.toObject()); JS::RootedObject it(m->m_cx, JS_NewPropertyIterator(m->m_cx, obj)); if (!it) return false; while (true) { JS::RootedId idp(m->m_cx); JS::RootedValue val(m->m_cx); if (! JS_NextProperty(m->m_cx, it, idp.address()) || ! JS_IdToValue(m->m_cx, idp, &val)) return false; if (val.isUndefined()) break; // end of iteration if (!val.isString()) continue; // ignore integer properties JS::RootedString name(m->m_cx, val.toString()); size_t len = strlen(prefix)+1; std::vector<char> buf(len); size_t prefixLen = strlen(prefix) * sizeof(char); JS_EncodeStringToBuffer(m->m_cx, name, &buf[0], prefixLen); buf[len-1]= '\0'; if(0 == strcmp(&buf[0], prefix)) { size_t len; const jschar* chars = JS_GetStringCharsAndLength(m->m_cx, name, &len); out.push_back(std::string(chars, chars+len)); } } // Recurse up the prototype chain JS::RootedObject prototype(m->m_cx); if (JS_GetPrototype(m->m_cx, obj, &prototype)) { JS::RootedValue prototypeVal(m->m_cx, JS::ObjectOrNullValue(prototype)); if (! EnumeratePropertyNamesWithPrefix(prototypeVal, prefix, out)) return false; } return true; }
nsresult XPCJSStackFrame::CreateStack(JSContext* cx, XPCJSStackFrame** stack) { static const unsigned MAX_FRAMES = 100; nsRefPtr<XPCJSStackFrame> first = new XPCJSStackFrame(); nsRefPtr<XPCJSStackFrame> self = first; JS::StackDescription* desc = JS::DescribeStack(cx, MAX_FRAMES); if (!desc) return NS_ERROR_FAILURE; for (size_t i = 0; i < desc->nframes && self; i++) { self->mLanguage = nsIProgrammingLanguage::JAVASCRIPT; JSAutoCompartment ac(cx, desc->frames[i].script); const char* filename = JS_GetScriptFilename(cx, desc->frames[i].script); if (filename) { self->mFilename = (char*) nsMemory::Clone(filename, sizeof(char)*(strlen(filename)+1)); } self->mLineno = desc->frames[i].lineno; JSFunction* fun = desc->frames[i].fun; if (fun) { JS::RootedString funid(cx, JS_GetFunctionDisplayId(fun)); if (funid) { size_t length = JS_GetStringEncodingLength(cx, funid); if (length != size_t(-1)) { self->mFunname = static_cast<char *>(nsMemory::Alloc(length + 1)); if (self->mFunname) { JS_EncodeStringToBuffer(cx, funid, self->mFunname, length); self->mFunname[length] = '\0'; } } } } XPCJSStackFrame* frame = new XPCJSStackFrame(); self->mCaller = frame; self = frame; } JS::FreeStackDescription(cx, desc); *stack = first.forget().get(); return NS_OK; }
static bool JSOBJECT_TO_CSTRING(jsval jsObj, char* buf, size_t bufSize) { if (!JSVAL_IS_STRING(jsObj)) return false; JSString* jsStr = JSVAL_TO_STRING(jsObj); if (!jsStr) return false; size_t bufLen = JS_EncodeStringToBuffer(jsStr, buf, (bufSize - 1)); buf[bufLen] = '\0'; return true; }
static JSBool _egueb_script_js_sm_scripter_alert(JSContext *cx, uintN argc, jsval *vp) { JSString* u16_txt; unsigned int length; char *txt; if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "S", &u16_txt)) return JS_FALSE; length = JS_GetStringEncodingLength(cx, u16_txt); txt = alloca(sizeof(char) * (length + 1)); JS_EncodeStringToBuffer(u16_txt, txt, length); printf("%.*s\n", length, txt); return JS_TRUE; }
int run(JSContext * cx) { /* Enter a request before running anything in the context */ JSAutoRequest ar(cx); /* Create the global object in a new compartment. */ JSObject *global = JS_NewGlobalObject(cx, &global_class, nullptr); if (!global) return 3; /* Set the context's global */ JSAutoCompartment ac(cx, global); JS_SetGlobalObject(cx, global); /* Populate the global object with the standard globals, like Object and Array. */ if (!JS_InitStandardClasses(cx, global)) return 4; /* Your application code here. This may include JSAPI calls to create your own custom JS objects and run scripts. */ js::RootedValue rval(cx); int rc = JS_EvaluateScript(cx, global, runCommand, strlen(runCommand), "TestCommand", 0, rval.address()); if (!rc) return 5; if (!JSVAL_IS_STRING(rval)) return 0; /* Result of the command is a string, print it out. */ js::RootedString str(cx, JSVAL_TO_STRING(rval)); size_t encodedLength = JS_GetStringEncodingLength(cx, str); rc = 0; char *buffer = (char *)malloc(encodedLength + 1); buffer[encodedLength] = '\0'; size_t result = JS_EncodeStringToBuffer(cx, str, buffer, encodedLength); if (result == (size_t) - 1) rc = 6; else puts(buffer); free(buffer); return rc; }
static bool JSSTRING_TO_STDSTRING(JSContext *cx, jsval *vp, size_t argn, std::string *stdStr) { jsval *argv = JS_ARGV(cx, vp); jsval arg = argv[argn]; if (!JSVAL_IS_STRING(arg)) return false; JSString *jsStr = JSVAL_TO_STRING(arg); if (!jsStr) return false; char buffer[1024]; size_t bufferLen = JS_EncodeStringToBuffer(jsStr, buffer, (sizeof(buffer)-1)); buffer[bufferLen] = '\0'; *stdStr = buffer; return true; }
bool GetOVRString(JSContext* cx, JS::HandleString s, OVR::String* out) { // Fill a buffer with the string data size_t sLen = JS_GetStringEncodingLength(cx, s) * sizeof(char); char* sBuf = new char[sLen+1]; size_t sCopiedLen = JS_EncodeStringToBuffer(cx, s, sBuf, sLen); if (sCopiedLen != sLen) { delete[] sBuf; JS_ReportError(cx, "Could not encode output"); return false; } sBuf[sLen] = '\0'; // Create the string to return from the buffer // TODO: See whether we can avoid this extra string copy *out = OVR::String(sBuf); // Make sure we free the buffer before returning our string delete[] sBuf; return true; }
bool ScriptInterface::EnumeratePropertyNamesWithPrefix(JS::HandleValue objVal, const char* prefix, std::vector<std::string>& out) { JSAutoRequest rq(m->m_cx); if (!objVal.isObjectOrNull()) { LOGERROR("EnumeratePropertyNamesWithPrefix expected object type!"); return false; } if (objVal.isNull()) return true; // reached the end of the prototype chain JS::RootedObject obj(m->m_cx, &objVal.toObject()); JS::AutoIdArray props(m->m_cx, JS_Enumerate(m->m_cx, obj)); if (!props) return false; for (size_t i = 0; i < props.length(); ++i) { JS::RootedId id(m->m_cx, props[i]); JS::RootedValue val(m->m_cx); if (!JS_IdToValue(m->m_cx, id, &val)) return false; if (!val.isString()) continue; // ignore integer properties JS::RootedString name(m->m_cx, val.toString()); size_t len = strlen(prefix)+1; std::vector<char> buf(len); size_t prefixLen = strlen(prefix) * sizeof(char); JS_EncodeStringToBuffer(m->m_cx, name, &buf[0], prefixLen); buf[len-1]= '\0'; if (0 == strcmp(&buf[0], prefix)) { if (JS_StringHasLatin1Chars(name)) { size_t length; JS::AutoCheckCannotGC nogc; const JS::Latin1Char* chars = JS_GetLatin1StringCharsAndLength(m->m_cx, nogc, name, &length); if (chars) out.push_back(std::string(chars, chars+length)); } else { size_t length; JS::AutoCheckCannotGC nogc; const char16_t* chars = JS_GetTwoByteStringCharsAndLength(m->m_cx, nogc, name, &length); if (chars) out.push_back(std::string(chars, chars+length)); } } } // Recurse up the prototype chain JS::RootedObject prototype(m->m_cx); if (JS_GetPrototype(m->m_cx, obj, &prototype)) { JS::RootedValue prototypeVal(m->m_cx, JS::ObjectOrNullValue(prototype)); if (!EnumeratePropertyNamesWithPrefix(prototypeVal, prefix, out)) return false; } return true; }