JSBool JSI_Console::getProperty(JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsid id, jsval* vp) { if (!JSID_IS_INT(id)) return JS_TRUE; int i = JSID_TO_INT(id); switch (i) { case console_visible: *vp = BOOLEAN_TO_JSVAL(g_Console->IsActive()); return JS_TRUE; default: *vp = JSVAL_NULL; return JS_TRUE; } }
/* @bookmark_class.getProperty */ static JSBool bookmark_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) { struct bookmark *bookmark; /* This can be called if @obj if not itself an instance of the * appropriate class but has one in its prototype chain. Fail * such calls. */ if (!JS_InstanceOf(ctx, obj, (JSClass *) &bookmark_class, NULL)) return JS_FALSE; bookmark = JS_GetInstancePrivate(ctx, obj, (JSClass *) &bookmark_class, NULL); if (!bookmark) return JS_FALSE; undef_to_jsval(ctx, vp); if (!JSID_IS_INT(id)) return JS_FALSE; switch (JSID_TO_INT(id)) { case BOOKMARK_TITLE: return bookmark_string_to_jsval(ctx, bookmark->title, vp); case BOOKMARK_URL: return bookmark_string_to_jsval(ctx, bookmark->url, vp); case BOOKMARK_CHILDREN: *vp = OBJECT_TO_JSVAL(smjs_get_bookmark_folder_object(bookmark)); return JS_TRUE; default: /* Unrecognized integer property ID; someone is using * the object as an array. SMJS builtin classes (e.g. * js_RegExpClass) just return JS_TRUE in this case * and leave *@vp unchanged. Do the same here. * (Actually not quite the same, as we already used * @undef_to_jsval.) */ return JS_TRUE; } }
/* @location_class.getProperty */ static JSBool location_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) { JSObject *parent_win; /* instance of @window_class */ struct view_state *vs; /* This can be called if @obj if not itself an instance of the * appropriate class but has one in its prototype chain. Fail * such calls. */ if (!JS_InstanceOf(ctx, obj, (JSClass *) &location_class, NULL)) return JS_FALSE; parent_win = JS_GetParent(ctx, obj); assert(JS_InstanceOf(ctx, parent_win, (JSClass *) &window_class, NULL)); if_assert_failed return JS_FALSE; vs = (struct view_state *)JS_GetInstancePrivate(ctx, parent_win, (JSClass *) &window_class, NULL); if (!JSID_IS_INT(id)) return JS_TRUE; undef_to_jsval(ctx, vp); switch (JSID_TO_INT(id)) { case JSP_LOC_HREF: astring_to_jsval(ctx, vp, get_uri_string(vs->uri, URI_ORIGINAL)); break; default: /* Unrecognized integer property ID; someone is using * the object as an array. SMJS builtin classes (e.g. * js_RegExpClass) just return JS_TRUE in this case * and leave *@vp unchanged. Do the same here. * (Actually not quite the same, as we already used * @undef_to_jsval.) */ break; } return JS_TRUE; }
JSBool JSI_Console::setProperty(JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsid id, jsval* vp) { if (!JSID_IS_INT(id)) return JS_TRUE; int i = JSID_TO_INT(id); switch (i) { case console_visible: try { g_Console->SetVisible(ToPrimitive<bool> (*vp)); return JS_TRUE; } catch (PSERROR_Scripting_ConversionFailed) { return JS_TRUE; } default: return JS_TRUE; } }
bool PluginIdentifierParent::RecvRetain() { mTemporaryRefs = 0; // Intern the jsid if necessary. AutoSafeJSContext cx; JS::Rooted<jsid> id(cx, NPIdentifierToJSId(mIdentifier)); if (JSID_IS_INT(id)) { return true; } // The following is what nsNPAPIPlugin.cpp does. Gross, but the API doesn't // give you a NPP to play with. JS::RootedString str(cx, JSID_TO_STRING(id)); JSString* str2 = JS_InternJSString(cx, str); if (!str2) { return false; } NS_ASSERTION(str == str2, "Interning a string in a JSID should always return the same string."); return true; }
JSBool RUST_JSID_IS_INT(jsid id) { return JSID_IS_INT(id); }
bool ExposedPropertiesOnly::check(JSContext* cx, HandleObject wrapper, HandleId id, Wrapper::Action act) { RootedObject wrappedObject(cx, Wrapper::wrappedObject(wrapper)); if (act == Wrapper::CALL) return false; // For the case of getting a property descriptor, we allow if either GET or SET // is allowed, and rely on FilteringWrapper to filter out any disallowed accessors. if (act == Wrapper::GET_PROPERTY_DESCRIPTOR) { return check(cx, wrapper, id, Wrapper::GET) || check(cx, wrapper, id, Wrapper::SET); } RootedId exposedPropsId(cx, GetRTIdByIndex(cx, XPCJSRuntime::IDX_EXPOSEDPROPS)); // We need to enter the wrappee's compartment to look at __exposedProps__, // but we want to be in the wrapper's compartment if we call Deny(). // // Unfortunately, |cx| can be in either compartment when we call ::check. :-( JSAutoCompartment ac(cx, wrappedObject); bool found = false; if (!JS_HasPropertyById(cx, wrappedObject, exposedPropsId, &found)) return false; // If no __exposedProps__ existed, deny access. if (!found) { // Previously we automatically granted access to indexed properties and // .length for Array COWs. We're not doing that anymore, so make sure to // let people know what's going on. bool isArray; if (!JS_IsArrayObject(cx, wrappedObject, &isArray)) return false; if (!isArray) isArray = JS_IsTypedArrayObject(wrappedObject); bool isIndexedAccessOnArray = isArray && JSID_IS_INT(id) && JSID_TO_INT(id) >= 0; bool isLengthAccessOnArray = isArray && JSID_IS_STRING(id) && JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(id), "length"); if (isIndexedAccessOnArray || isLengthAccessOnArray) { JSAutoCompartment ac2(cx, wrapper); ReportWrapperDenial(cx, id, WrapperDenialForCOW, "Access to elements and length of privileged Array not permitted"); } return false; } if (id == JSID_VOID) return true; Rooted<JSPropertyDescriptor> desc(cx); if (!JS_GetPropertyDescriptorById(cx, wrappedObject, exposedPropsId, &desc)) return false; if (!desc.object()) return false; if (desc.hasGetterOrSetter()) { EnterAndThrow(cx, wrapper, "__exposedProps__ must be a value property"); return false; } RootedValue exposedProps(cx, desc.value()); if (exposedProps.isNullOrUndefined()) return false; if (!exposedProps.isObject()) { EnterAndThrow(cx, wrapper, "__exposedProps__ must be undefined, null, or an Object"); return false; } RootedObject hallpass(cx, &exposedProps.toObject()); if (!AccessCheck::subsumes(js::UncheckedUnwrap(hallpass), wrappedObject)) { EnterAndThrow(cx, wrapper, "Invalid __exposedProps__"); return false; } Access access = NO_ACCESS; if (!JS_GetPropertyDescriptorById(cx, hallpass, id, &desc)) { return false; // Error } if (!desc.object() || !desc.enumerable()) return false; if (!desc.value().isString()) { EnterAndThrow(cx, wrapper, "property must be a string"); return false; } JSFlatString* flat = JS_FlattenString(cx, desc.value().toString()); if (!flat) return false; size_t length = JS_GetStringLength(JS_FORGET_STRING_FLATNESS(flat)); for (size_t i = 0; i < length; ++i) { char16_t ch = JS_GetFlatStringCharAt(flat, i); switch (ch) { case 'r': if (access & READ) { EnterAndThrow(cx, wrapper, "duplicate 'readable' property flag"); return false; } access = Access(access | READ); break; case 'w': if (access & WRITE) { EnterAndThrow(cx, wrapper, "duplicate 'writable' property flag"); return false; } access = Access(access | WRITE); break; default: EnterAndThrow(cx, wrapper, "properties can only be readable or read and writable"); return false; } } if (access == NO_ACCESS) { EnterAndThrow(cx, wrapper, "specified properties must have a permission bit set"); return false; } if ((act == Wrapper::SET && !(access & WRITE)) || (act != Wrapper::SET && !(access & READ))) { return false; } // Inspect the property on the underlying object to check for red flags. if (!JS_GetPropertyDescriptorById(cx, wrappedObject, id, &desc)) return false; // Reject accessor properties. if (desc.hasGetterOrSetter()) { EnterAndThrow(cx, wrapper, "Exposing privileged accessor properties is prohibited"); return false; } // Reject privileged or cross-origin callables. if (desc.value().isObject()) { RootedObject maybeCallable(cx, js::UncheckedUnwrap(&desc.value().toObject())); if (JS::IsCallable(maybeCallable) && !AccessCheck::subsumes(wrapper, maybeCallable)) { EnterAndThrow(cx, wrapper, "Exposing privileged or cross-origin callable is prohibited"); return false; } } return true; }
uint32_t IdWrapper::toInt32() const { uassert(ErrorCodes::TypeMismatch, "Cannot toInt32() non-integer jsid", JSID_IS_INT(_value)); return JSID_TO_INT(_value); }
bool IdWrapper::isInt() const { return JSID_IS_INT(_value); }
/* @cache_entry_class.getProperty */ static JSBool cache_entry_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) { struct cache_entry *cached; JSBool ret; /* This can be called if @obj if not itself an instance of the * appropriate class but has one in its prototype chain. Fail * such calls. */ if (!JS_InstanceOf(ctx, obj, (JSClass *) &cache_entry_class, NULL)) return JS_FALSE; cached = JS_GetInstancePrivate(ctx, obj, (JSClass *) &cache_entry_class, NULL); if (!cached) return JS_FALSE; /* already detached */ assert(cache_entry_is_valid(cached)); if_assert_failed return JS_FALSE; /* Get a strong reference to the cache entry to prevent it * from being deleted if some function called below decides to * collect garbage. After this, all code paths must * eventually unlock the object. */ object_lock(cached); undef_to_jsval(ctx, vp); if (!JSID_IS_INT(id)) ret = JS_FALSE; else switch (JSID_TO_INT(id)) { case CACHE_ENTRY_CONTENT: { struct fragment *fragment = get_cache_fragment(cached); if (!fragment) { ret = JS_FALSE; break; } *vp = STRING_TO_JSVAL(JS_NewStringCopyN(smjs_ctx, fragment->data, fragment->length)); ret = JS_TRUE; break; } case CACHE_ENTRY_TYPE: *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx, cached->content_type)); ret = JS_TRUE; break; case CACHE_ENTRY_HEAD: *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx, cached->head)); ret = JS_TRUE; break; case CACHE_ENTRY_LENGTH: *vp = INT_TO_JSVAL(cached->length); ret = JS_TRUE; break; case CACHE_ENTRY_URI: *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx, struri(cached->uri))); ret = JS_TRUE; break; default: /* Unrecognized integer property ID; someone is using * the object as an array. SMJS builtin classes (e.g. * js_RegExpClass) just return JS_TRUE in this case * and leave *@vp unchanged. Do the same here. * (Actually not quite the same, as we already used * @undef_to_jsval.) */ ret = JS_TRUE; break; } object_unlock(cached); return ret; }
/* @cache_entry_class.setProperty */ static JSBool cache_entry_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp) { struct cache_entry *cached; JSBool ret; /* This can be called if @obj if not itself an instance of the * appropriate class but has one in its prototype chain. Fail * such calls. */ if (!JS_InstanceOf(ctx, obj, (JSClass *) &cache_entry_class, NULL)) return JS_FALSE; cached = JS_GetInstancePrivate(ctx, obj, (JSClass *) &cache_entry_class, NULL); if (!cached) return JS_FALSE; /* already detached */ assert(cache_entry_is_valid(cached)); if_assert_failed return JS_FALSE; /* Get a strong reference to the cache entry to prevent it * from being deleted if some function called below decides to * collect garbage. After this, all code paths must * eventually unlock the object. */ object_lock(cached); if (!JSID_IS_INT(id)) ret = JS_FALSE; else switch (JSID_TO_INT(id)) { case CACHE_ENTRY_CONTENT: { JSString *jsstr = JS_ValueToString(smjs_ctx, *vp); unsigned char *str = JS_EncodeString(smjs_ctx, jsstr); size_t len = JS_GetStringLength(jsstr); add_fragment(cached, 0, str, len); normalize_cache_entry(cached, len); ret = JS_TRUE; break; } case CACHE_ENTRY_TYPE: { JSString *jsstr = JS_ValueToString(smjs_ctx, *vp); unsigned char *str = JS_EncodeString(smjs_ctx, jsstr); mem_free_set(&cached->content_type, stracpy(str)); ret = JS_TRUE; break; } case CACHE_ENTRY_HEAD: { JSString *jsstr = JS_ValueToString(smjs_ctx, *vp); unsigned char *str = JS_EncodeString(smjs_ctx, jsstr); mem_free_set(&cached->head, stracpy(str)); ret = JS_TRUE; break; } default: /* Unrecognized integer property ID; someone is using * the object as an array. SMJS builtin classes (e.g. * js_RegExpClass) just return JS_TRUE in this case. * Do the same here. */ ret = JS_TRUE; break; } object_unlock(cached); return ret; }
/* @smjs_globhist_item_class.getProperty */ static JSBool smjs_globhist_item_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) { struct global_history_item *history_item; /* This can be called if @obj if not itself an instance of the * appropriate class but has one in its prototype chain. Fail * such calls. */ if (!JS_InstanceOf(ctx, obj, (JSClass *) &smjs_globhist_item_class, NULL)) return JS_FALSE; history_item = JS_GetInstancePrivate(ctx, obj, (JSClass *) &smjs_globhist_item_class, NULL); if (!history_item) return JS_FALSE; undef_to_jsval(ctx, vp); if (!JSID_IS_INT(id)) return JS_FALSE; switch (JSID_TO_INT(id)) { case GLOBHIST_TITLE: *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx, history_item->title)); return JS_TRUE; case GLOBHIST_URL: *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx, history_item->url)); return JS_TRUE; case GLOBHIST_LAST_VISIT: /* TODO: I'd rather return a date object, but that introduces * synchronisation issues: * * - How do we cause a change to that date object to affect * the actual global history item? * - How do we get a change to that global history item * to affect all date objects? * * The biggest obstacle is that we have no way to trigger code * when one messes with the date object. * * -- Miciah */ /* XXX: Currently, ECMAScript gets seconds since the epoch. * Since the Date object uses milliseconds since the epoch, * I'd rather export that, but SpiderMonkey doesn't provide * a suitable type. -- Miciah */ JS_NewNumberValue(smjs_ctx, history_item->last_visit, vp); return JS_TRUE; default: /* Unrecognized integer property ID; someone is using * the object as an array. SMJS builtin classes (e.g. * js_RegExpClass) just return JS_TRUE in this case * and leave *@vp unchanged. Do the same here. * (Actually not quite the same, as we already used * @undef_to_jsval.) */ return JS_TRUE; } }
bool ExposedPropertiesOnly::check(JSContext *cx, HandleObject wrapper, HandleId id, Wrapper::Action act) { RootedObject wrappedObject(cx, Wrapper::wrappedObject(wrapper)); if (act == Wrapper::CALL) return true; // For the case of getting a property descriptor, we allow if either GET or SET // is allowed, and rely on FilteringWrapper to filter out any disallowed accessors. if (act == Wrapper::GET_PROPERTY_DESCRIPTOR) { return check(cx, wrapper, id, Wrapper::GET) || check(cx, wrapper, id, Wrapper::SET); } RootedId exposedPropsId(cx, GetRTIdByIndex(cx, XPCJSRuntime::IDX_EXPOSEDPROPS)); // We need to enter the wrappee's compartment to look at __exposedProps__, // but we want to be in the wrapper's compartment if we call Deny(). // // Unfortunately, |cx| can be in either compartment when we call ::check. :-( JSAutoCompartment ac(cx, wrappedObject); bool found = false; if (!JS_HasPropertyById(cx, wrappedObject, exposedPropsId, &found)) return false; // Always permit access to "length" and indexed properties of arrays. if ((JS_IsArrayObject(cx, wrappedObject) || JS_IsTypedArrayObject(wrappedObject)) && ((JSID_IS_INT(id) && JSID_TO_INT(id) >= 0) || (JSID_IS_STRING(id) && JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(id), "length")))) { return true; // Allow } // If no __exposedProps__ existed, deny access. if (!found) { return false; } if (id == JSID_VOID) return true; RootedValue exposedProps(cx); if (!JS_LookupPropertyById(cx, wrappedObject, exposedPropsId, &exposedProps)) return false; if (exposedProps.isNullOrUndefined()) return false; if (!exposedProps.isObject()) { EnterAndThrow(cx, wrapper, "__exposedProps__ must be undefined, null, or an Object"); return false; } RootedObject hallpass(cx, &exposedProps.toObject()); if (!AccessCheck::subsumes(js::UncheckedUnwrap(hallpass), wrappedObject)) { EnterAndThrow(cx, wrapper, "Invalid __exposedProps__"); return false; } Access access = NO_ACCESS; Rooted<JSPropertyDescriptor> desc(cx); if (!JS_GetPropertyDescriptorById(cx, hallpass, id, &desc)) { return false; // Error } if (!desc.object() || !desc.isEnumerable()) return false; if (!desc.value().isString()) { EnterAndThrow(cx, wrapper, "property must be a string"); return false; } JSFlatString *flat = JS_FlattenString(cx, desc.value().toString()); if (!flat) return false; size_t length = JS_GetStringLength(JS_FORGET_STRING_FLATNESS(flat)); for (size_t i = 0; i < length; ++i) { char16_t ch = JS_GetFlatStringCharAt(flat, i); switch (ch) { case 'r': if (access & READ) { EnterAndThrow(cx, wrapper, "duplicate 'readable' property flag"); return false; } access = Access(access | READ); break; case 'w': if (access & WRITE) { EnterAndThrow(cx, wrapper, "duplicate 'writable' property flag"); return false; } access = Access(access | WRITE); break; default: EnterAndThrow(cx, wrapper, "properties can only be readable or read and writable"); return false; } } if (access == NO_ACCESS) { EnterAndThrow(cx, wrapper, "specified properties must have a permission bit set"); return false; } if ((act == Wrapper::SET && !(access & WRITE)) || (act != Wrapper::SET && !(access & READ))) { return false; } return true; }
JSBool JsGlobal::event_GetProperty (JSContext *cx, JSObject *obj, jsid id, jsval *vp) { fsm::StateMachine * pstateMachine = NULL; static log4cplus::Logger log = log4cplus::Logger::getInstance("TUserManager.GetProperty"); pstateMachine = (fsm::StateMachine *)JS_GetContextPrivate(cx); if (!pstateMachine){ LOG4CPLUS_WARN(log,"GetContextPrivate is null."); } if (!JSID_IS_INT(id)) return JS_TRUE; int proid = JSID_TO_INT(id); jsval *val = (jsval *) JS_GetPrivate(cx, obj); if (val) { if(JSVAL_IS_NULL(*vp) || JSVAL_IS_VOID(*vp)) *vp = val[proid]; return JS_TRUE; } val = new jsval[4]; if (!val) { JS_ReportOutOfMemory(cx); JS_SET_RVAL(cx, vp, JSVAL_VOID); return JS_TRUE; } if (!JS_AddValueRoot(cx, val)) { delete[] val; JS_SET_RVAL(cx, vp, JSVAL_VOID); return JS_TRUE; } if (!JS_SetPrivate(cx, obj, (void*)val)) { JS_RemoveValueRoot(cx, val); delete[] val; JS_SET_RVAL(cx, vp, JSVAL_VOID); return JS_TRUE; } std::string prefix = "getting [_event] property:"; fsm::env::Js::IdToString idString(cx, id); if(pstateMachine ){ val[name] = STRING_TO_JSVAL(JS_NewStringCopyZ (cx,pstateMachine->m_currentEvt.getEventName().c_str())); //val[bodydata] = STRING_TO_JSVAL(JS_NewStringCopyZ (cx,pstateMachine->m_currentEvt.getData().c_str())); //val[messagetype] = STRING_TO_JSVAL(JS_NewStringCopyZ (cx,pstateMachine->m_currentEvt.getMsgType().c_str())); //val[ip] = STRING_TO_JSVAL(JS_NewStringCopyZ (cx,pstateMachine->m_currentEvt.getIP().c_str())); //val[port] = INT_TO_JSVAL(pstateMachine->m_currentEvt.getPort()); val[serviceid] = STRING_TO_JSVAL(JS_NewStringCopyZ (cx,pstateMachine->getName().c_str())); val[sessionid] = STRING_TO_JSVAL(JS_NewStringCopyZ (cx,pstateMachine->getSessionId().c_str())); val[callid] = STRING_TO_JSVAL(JS_NewStringCopyZ (cx,pstateMachine->getSessionId().c_str())); switch (proid) { case name: prefix.append("_name"); break; case serviceid: prefix.append("_serviceid"); break; case sessionid: prefix.append("_sessionid"); break; case callid: prefix.append("_callid"); break; //case from:{ // vp.setInt32(pstateMachine->getFrom().c_str()); // break; //case Enable: // vp.setBoolean(extPtr->m_bEnable); // break; default: prefix.append(idString.getBytes()); break; } }else{ prefix.append(idString.getBytes()); } fsm::env::Js::ToString valueString(cx, val[proid]); //fsm::env::Js::ToString objString(cx,OBJECT_TO_JSVAL(obj)); *vp = val[proid]; LOG4CPLUS_DEBUG(log,prefix<< ",value:" << valueString.getBytes()); return JS_TRUE; }