static JSObject * define_JavaPackage(JSContext *cx, JSObject *parent_obj, const char *obj_name, const char *path, int flags, int access) { JSObject *package_obj; JavaPackage_Private *package; package_obj = JS_DefineObject(cx, parent_obj, obj_name, &JavaPackage_class, 0, JSPROP_PERMANENT | access); if (!package_obj) return NULL; /* Attach private, native data to the JS object */ package = (JavaPackage_Private *)JS_malloc(cx, sizeof(JavaPackage_Private)); JS_SetPrivate(cx, package_obj, (void *)package); if (path) package->path = JS_strdup(cx, path); else package->path = ""; package->flags = flags; /* Check for OOM */ if (!package->path) { JS_DeleteProperty(cx, parent_obj, obj_name); JS_free(cx, package); return NULL; } return package_obj; }
static JSBool ejs_mkdtemp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { EJS_CHECK_TRUSTED(cx,obj); EJS_CHECK_NUM_ARGS(cx,obj,1,argc); JSString *strtype=JS_ValueToString(cx, argv[0]); // todo: we loose unicode information here char* ctype=JS_GetStringBytes(strtype); if (!ctype) return JS_FALSE; char* nstr=JS_strdup(cx,ctype); if (!nstr) return JS_FALSE; if (!mkdtemp(nstr)) { JS_free(cx,nstr); *rval=JSVAL_FALSE; return JS_TRUE; } JSString *jsnstr=JS_NewString(cx, nstr, strlen(nstr)); if (!jsnstr) { JS_free(cx,nstr); return JS_FALSE; } *rval=STRING_TO_JSVAL(jsnstr); return JS_TRUE; }
static JSObject * define_JavaPackage(JSContext *cx, JSObject *parent_obj, const char *obj_name, const char *path, int flags, int access) { JSObject *package_obj, *obj; JavaPackage_Private *package; jsval v; /* * Expose the same JSObject for Packages.java and java. * "java" will be defined during the java package initialization stage. * "Packages.java" will be lazily resolved by JavaPackage_resolve. * Ditto for sun and netscape. * See bugzilla bug: https://bugzilla.mozilla.org/show_bug.cgi?id=248409. */ if (!strcmp(obj_name, path) && (obj = JS_GetParent(cx, parent_obj)) && JS_LookupProperty(cx, obj, obj_name, &v) && !JSVAL_IS_PRIMITIVE(v)) { if (!JS_DefineProperty(cx, parent_obj, obj_name, v, NULL, NULL, JSPROP_PERMANENT | access)) { return NULL; } package_obj = JSVAL_TO_OBJECT(v); return package_obj; } package_obj = JS_DefineObject(cx, parent_obj, obj_name, &JavaPackage_class, 0, JSPROP_PERMANENT | access); if (!package_obj) return NULL; /* Attach private, native data to the JS object */ package = (JavaPackage_Private *)JS_malloc(cx, sizeof(JavaPackage_Private)); if (!package) { JS_DeleteProperty(cx, parent_obj, obj_name); return NULL; } JS_SetPrivate(cx, package_obj, (void *)package); if (path) package->path = JS_strdup(cx, path); else package->path = ""; package->flags = flags; /* Check for OOM */ if (!package->path) { JS_DeleteProperty(cx, parent_obj, obj_name); JS_free(cx, package); return NULL; } return package_obj; }
JSObject* Core_initialize (JSContext *cx, const char* path) { JS_BeginRequest(cx); JS_SetOptions(cx, JSOPTION_VAROBJFIX|JSOPTION_JIT|JSOPTION_XML); JS_SetVersion(cx, JS_StringToVersion("1.8")); JSObject* object = JS_NewObject(cx, &Core_class, NULL, NULL); if (object && JS_InitStandardClasses(cx, object)) { JS_DefineFunctions(cx, object, Core_methods); JS_EnterLocalRootScope(cx); // Properties jsval property; std::string rootPath = __Core_getRootPath(cx, path); jsval paths[] = { STRING_TO_JSVAL(JS_NewString(cx, JS_strdup(cx, rootPath.c_str()), rootPath.length())), STRING_TO_JSVAL(JS_NewString(cx, JS_strdup(cx, __LJS_LIBRARY_PATH__), strlen(__LJS_LIBRARY_PATH__))) }; property = OBJECT_TO_JSVAL(JS_NewArrayObject(cx, 2, paths)); JS_SetProperty(cx, object, "__PATH__", &property); property = STRING_TO_JSVAL(JS_NewString(cx, JS_strdup(cx, __LJS_VERSION__), strlen(__LJS_VERSION__))); JS_SetProperty(cx, object, "__VERSION__", &property); property = OBJECT_TO_JSVAL(object); JS_SetProperty(cx, object, "Program", &property); JS_LeaveLocalRootScope(cx); JS_EndRequest(cx); if (__Core_include(cx, __LJS_LIBRARY_PATH__ "/Core")) { return object; } } return NULL; }
JSBool js_ObjectIs (JSContext* cx, jsval check, const char* name) { jsval jsObj; JS_GetProperty(cx, JS_GetGlobalObject(cx), "Object", &jsObj); JSObject* Obj = JSVAL_TO_OBJECT(jsObj); jsval newArgv[] = { check, STRING_TO_JSVAL(JS_NewString(cx, JS_strdup(cx, name), strlen(name))) }; jsval ret; JS_CallFunctionName(cx, Obj, "is", 2, newArgv, &ret); return JSVAL_TO_BOOLEAN(ret); }
/* * Return a UTF8, null-terminated encoding of a Java string. The string must * be free'ed by the caller. * * If an error occurs, returns NULL and calls the JS error reporter. */ const char * jsj_DupJavaStringUTF(JSContext *cx, JNIEnv *jEnv, jstring jstr) { const char *str, *retval; str = (*jEnv)->GetStringUTFChars(jEnv, jstr, 0); if (!str) { jsj_UnexpectedJavaError(cx, jEnv, "Can't get UTF8 characters from " "Java string"); return NULL; } retval = JS_strdup(cx, str); (*jEnv)->ReleaseStringUTFChars(jEnv, jstr, str); return retval; }
js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *reportp) { JSErrorReporter onError; if (!message) return; if (cx->lastMessage) free(cx->lastMessage); cx->lastMessage = JS_strdup(cx, message); if (!cx->lastMessage) return; onError = cx->errorReporter; if (onError) (*onError)(cx, cx->lastMessage, reportp); }
static JSBool url_load(JSContext *cx, JSObject *obj, const char *url_string, NET_ReloadMethod reload_how) { JSURL *url; URL_Struct *url_struct; const char *referer; url = JS_GetPrivate(cx, obj); if (!url) return JS_TRUE; url_struct = NET_CreateURLStruct(url_string, reload_how); if (!url_struct) { JS_ReportOutOfMemory(cx); return JS_FALSE; } if (!(referer = lm_GetSubjectOriginURL(cx)) || !(url_struct->referer = JS_strdup(cx, referer))) { NET_FreeURLStruct(url_struct); return JS_FALSE; } return lm_GetURL(cx, url->url_decoder, url_struct); }
static JSBool xmlgraph_nameBySetter(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { JSString *namestr; XMLGraphCallback *cb = JS_GetPrivate(cx, obj); if (!cb) return JS_TRUE; if (*vp == JSVAL_NULL) { if (cb->nameBy) JS_free(cx, cb->nameBy); cb->nameBy = NULL; return JS_TRUE; } namestr = JS_ValueToString(cx, *vp); if (!namestr) return JS_FALSE; if (cb->nameBy) JS_free(cx, cb->nameBy); cb->nameBy = JS_strdup(cx, JS_GetStringBytes(namestr)); if (!cb->nameBy) return JS_FALSE; return JS_TRUE; }
JavaMemberDescriptor * jsj_GetJavaClassConstructors(JSContext *cx, JavaClassDescriptor *class_descriptor) { JavaMemberDescriptor *member_descriptor; if (class_descriptor->constructors) return class_descriptor->constructors; member_descriptor = JS_malloc(cx, sizeof(JavaMemberDescriptor)); if (!member_descriptor) return NULL; memset(member_descriptor, 0, sizeof(JavaMemberDescriptor)); member_descriptor->name = JS_strdup(cx, "<init>"); if (!member_descriptor->name) { JS_free(cx, member_descriptor); return NULL; } class_descriptor->constructors = member_descriptor; return member_descriptor; }
static JSBool global_resolve(JSContext *cx, JSHandleObject obj, JSHandleId id, unsigned flags, MutableHandleObject objp) { #ifdef LAZY_STANDARD_CLASSES if ((flags & JSRESOLVE_ASSIGNING) == 0) { JSBool resolved; if (!JS_ResolveStandardClass(cx, obj, id, &resolved)) return JS_FALSE; if (resolved) { objp.set(obj); return JS_TRUE; } } #endif #if defined(SHELL_HACK) && defined(DEBUG) && defined(XP_UNIX) if ((flags & (JSRESOLVE_QUALIFIED | JSRESOLVE_ASSIGNING)) == 0) { /* * Do this expensive hack only for unoptimized Unix builds, which are * not used for benchmarking. */ char *path, *comp, *full; const char *name; JSBool ok, found; JSFunction *fun; if (!JSVAL_IS_STRING(id)) return JS_TRUE; path = getenv("PATH"); if (!path) return JS_TRUE; path = JS_strdup(cx, path); if (!path) return JS_FALSE; name = JS_GetStringBytes(JSVAL_TO_STRING(id)); ok = JS_TRUE; for (comp = strtok(path, ":"); comp; comp = strtok(NULL, ":")) { if (*comp != '\0') { full = JS_smprintf("%s/%s", comp, name); if (!full) { JS_ReportOutOfMemory(cx); ok = JS_FALSE; break; } } else { full = (char *)name; } found = (access(full, X_OK) == 0); if (*comp != '\0') free(full); if (found) { fun = JS_DefineFunction(cx, obj, name, Exec, 0, JSPROP_ENUMERATE); ok = (fun != NULL); if (ok) objp.set(obj); break; } } JS_free(cx, path); return ok; } #else return JS_TRUE; #endif }
/** * Create a new GPSEE Realm. New realm will be initialized to have all members NULL, except * - the context and name provided (name only present in debug build) * - an initialized module system (and hence module data store) * - an initialized I/O hooks data store * - an initialized global object * - a prototype for the module object * * @param grt The GPSEE runtime to which the new realm will belong * @param name A symbolic name, for use in debugging, to describe this realm. Does not need to be unique. * * @returns The new realm, or NULL if we threw an exception. */ gpsee_realm_t *gpsee_createRealm(gpsee_runtime_t *grt, const char *name) { gpsee_realm_t *realm = NULL; JSContext *cx; cx = JS_NewContext(grt->rt, 8192); if (!cx) return NULL; JS_BeginRequest(cx); JS_SetOptions(cx, JS_GetOptions(grt->coreCx)); gpsee_enterAutoMonitor(cx, &grt->monitors.realms); realm = JS_malloc(cx, sizeof(*realm)); if (!realm) goto err_out; memset(realm, 0, sizeof(*realm)); realm->grt = grt; #ifdef GPSEE_DEBUG_BUILD realm->name = JS_strdup(cx, name); if (!realm->name) goto err_out; #endif realm->user_io_pendingWrites = gpsee_ds_create(grt, GPSEE_DS_OTM_KEYS, 0); if (!realm->user_io_pendingWrites) return JS_FALSE; #if defined(JSRESERVED_GLOBAL_COMPARTMENT) realm->globalObject = JS_NewCompartmentAndGlobalObject(cx, gpsee_getGlobalClass(), NULL); #else realm->globalObject = JS_NewGlobalObject(cx, gpsee_getGlobalClass()); #endif if (!realm->globalObject) goto err_out; { static JSClass moduleObjectClass = { GPSEE_GLOBAL_NAMESPACE_NAME ".Module", 0, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub }; #undef JS_InitClass moduleObjectClass.name += sizeof(GPSEE_GLOBAL_NAMESPACE_NAME); realm->moduleObjectProto = JS_InitClass(cx, realm->globalObject, NULL, &moduleObjectClass, ModuleObject, 0, NULL, NULL, NULL, NULL); moduleObjectClass.name -= sizeof(GPSEE_GLOBAL_NAMESPACE_NAME); realm->moduleObjectClass = &moduleObjectClass; #define JS_InitClass poison } if (!realm->moduleObjectProto) goto err_out; JS_AddNamedObjectRoot(cx, &realm->globalObject, "super-global"); if (gpsee_ds_put(grt->realms, realm, NULL) == JS_FALSE) goto err_out; if (gpsee_initializeModuleSystem(cx, realm) == JS_FALSE) panic("Unable to initialize module system"); if (gpsee_initGlobalObject(cx, realm, realm->globalObject) == JS_FALSE) goto err_out; realm->cachedCx = cx; goto out; err_out: if (realm) { JS_free(cx, realm); #ifdef GPSEE_DEBUG_BUILD if (realm->name) JS_free(cx, (char *)realm->name); #endif realm = NULL; } if (cx) { JS_DestroyContext(cx); cx = NULL; } out: gpsee_leaveAutoMonitor(grt->monitors.realms); if (cx) JS_EndRequest(cx); return realm; }
/* * The arguments from ap need to be packaged up into an array and stored * into the report struct. * * The format string addressed by the error number may contain operands * identified by the format {N}, where N is a decimal digit. Each of these * is to be replaced by the Nth argument from the va_list. The complete * message is placed into reportp->ucmessage converted to a JSString. * * Returns true if the expansion succeeds (can fail if out of memory). */ JSBool js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback, void *userRef, const uintN errorNumber, char **messagep, JSErrorReport *reportp, JSBool *warningp, JSBool charArgs, va_list ap) { const JSErrorFormatString *efs; int i; int argCount; *warningp = JSREPORT_IS_WARNING(reportp->flags); if (*warningp && JS_HAS_WERROR_OPTION(cx)) { reportp->flags &= ~JSREPORT_WARNING; *warningp = JS_FALSE; } *messagep = NULL; if (callback) { efs = callback(userRef, NULL, errorNumber); if (efs) { size_t totalArgsLength = 0; size_t argLengths[10]; /* only {0} thru {9} supported */ argCount = efs->argCount; JS_ASSERT(argCount <= 10); if (argCount > 0) { /* * Gather the arguments into an array, and accumulate * their sizes. We allocate 1 more than necessary and * null it out to act as the caboose when we free the * pointers later. */ reportp->messageArgs = (const jschar **) JS_malloc(cx, sizeof(jschar *) * (argCount + 1)); if (!reportp->messageArgs) return JS_FALSE; reportp->messageArgs[argCount] = NULL; for (i = 0; i < argCount; i++) { if (charArgs) { char *charArg = va_arg(ap, char *); reportp->messageArgs[i] = js_InflateString(cx, charArg, strlen(charArg)); if (!reportp->messageArgs[i]) goto error; } else reportp->messageArgs[i] = va_arg(ap, jschar *); argLengths[i] = js_strlen(reportp->messageArgs[i]); totalArgsLength += argLengths[i]; } /* NULL-terminate for easy copying. */ reportp->messageArgs[i] = NULL; } /* * Parse the error format, substituting the argument X * for {X} in the format. */ if (argCount > 0) { if (efs->format) { const char *fmt; const jschar *arg; jschar *out; int expandedArgs = 0; size_t expandedLength = strlen(efs->format) - (3 * argCount) /* exclude the {n} */ + totalArgsLength; /* * Note - the above calculation assumes that each argument * is used once and only once in the expansion !!! */ reportp->ucmessage = out = (jschar *) JS_malloc(cx, (expandedLength + 1) * sizeof(jschar)); if (!out) goto error; fmt = efs->format; while (*fmt) { if (*fmt == '{') { if (isdigit(fmt[1])) { int d = JS7_UNDEC(fmt[1]); JS_ASSERT(expandedArgs < argCount); arg = reportp->messageArgs[d]; js_strncpy(out, arg, argLengths[d]); out += argLengths[d]; fmt += 3; expandedArgs++; continue; } } /* * is this kosher? */ *out++ = (unsigned char)(*fmt++); } JS_ASSERT(expandedArgs == argCount); *out = 0; *messagep = js_DeflateString(cx, reportp->ucmessage, (size_t)(out - reportp->ucmessage)); if (!*messagep) goto error; } } else { /* * Zero arguments: the format string (if it exists) is the * entire message. */ if (efs->format) { *messagep = JS_strdup(cx, efs->format); if (!*messagep) goto error; reportp->ucmessage = js_InflateString(cx, *messagep, strlen(*messagep)); if (!reportp->ucmessage) goto error; } } }
/* * Copy everything interesting about an error into allocated memory. */ static JSExnPrivate * exn_newPrivate(JSContext *cx, JSErrorReport *report) { intN i; JSExnPrivate *newPrivate; JSErrorReport *newReport; size_t capacity; newPrivate = (JSExnPrivate *)JS_malloc(cx, sizeof (JSExnPrivate)); if (!newPrivate) return NULL; memset(newPrivate, 0, sizeof (JSExnPrivate)); /* Copy the error report */ newReport = (JSErrorReport *)JS_malloc(cx, sizeof (JSErrorReport)); if (!newReport) goto error; memset(newReport, 0, sizeof (JSErrorReport)); newPrivate->errorReport = newReport; if (report->filename != NULL) { newReport->filename = JS_strdup(cx, report->filename); if (!newReport->filename) goto error; } else { newReport->filename = NULL; } newReport->lineno = report->lineno; /* * We don't need to copy linebuf and tokenptr, because they * point into the deflated string cache. (currently?) */ newReport->linebuf = report->linebuf; newReport->tokenptr = report->tokenptr; /* * But we do need to copy uclinebuf, uctokenptr, because they're * pointers into internal tokenstream structs, and may go away. */ if (report->uclinebuf != NULL) { capacity = js_strlen(report->uclinebuf) + 1; newReport->uclinebuf = (const jschar *)JS_malloc(cx, capacity * sizeof(jschar)); if (!newReport->uclinebuf) goto error; js_strncpy((jschar *)newReport->uclinebuf, report->uclinebuf, capacity); newReport->uctokenptr = newReport->uclinebuf + (report->uctokenptr - report->uclinebuf); } else { newReport->uclinebuf = newReport->uctokenptr = NULL; } if (report->ucmessage != NULL) { capacity = js_strlen(report->ucmessage) + 1; newReport->ucmessage = (const jschar *)JS_malloc(cx, capacity * sizeof(jschar)); if (!newReport->ucmessage) goto error; js_strncpy((jschar *)newReport->ucmessage, report->ucmessage, capacity); if (report->messageArgs) { for (i = 0; report->messageArgs[i] != NULL; i++) continue; JS_ASSERT(i); newReport->messageArgs = (const jschar **)JS_malloc(cx, (i + 1) * sizeof(jschar *)); if (!newReport->messageArgs) goto error; for (i = 0; report->messageArgs[i] != NULL; i++) { capacity = js_strlen(report->messageArgs[i]) + 1; newReport->messageArgs[i] = (const jschar *)JS_malloc(cx, capacity * sizeof(jschar)); if (!newReport->messageArgs[i]) goto error; js_strncpy((jschar *)(newReport->messageArgs[i]), report->messageArgs[i], capacity); } newReport->messageArgs[i] = NULL; } else { newReport->messageArgs = NULL; } } else { newReport->ucmessage = NULL; newReport->messageArgs = NULL; } newReport->errorNumber = report->errorNumber; /* Note that this is before it gets flagged with JSREPORT_EXCEPTION */ newReport->flags = report->flags; return newPrivate; error: exn_destroyPrivate(cx, newPrivate); return NULL; }
/** Needs nargs to be at least 2 for GC roots. * * JS method returns true if values were read. */ static JSBool query_readQuery(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { extern cfgHnd cfg; query_private_t *hnd = JS_GetPrivate(cx, obj); node *n; JSString *str; int retval; jsrefcount depth; jsval val; if (hnd->query) return gpsee_throw(cx, OBJECT_ID ".readQuery.alreadyRead"); else hnd->query = JS_malloc(cx, sizeof(*hnd->query)); if (argc > 0) { str = JS_ValueToString(cx, argv[0]); hnd->uploadDir = JS_strdup(cx, JS_GetStringBytes(str)); } else hnd->uploadDir = cfg_value(cfg, OBJECT_ID ".default_upload_dir"); /* fix this later by making upload files == /dev/null in libcgihtml.so when upload dir is null */ if (!hnd->uploadDir) gpsee_log(cx, GLOG_NOTICE, "Unspecified upload dir is a security problem! Specify rc." OBJECT_ID ".default_upload_dir!"); depth = JS_SuspendRequest(cx); retval = read_cgi_input(cx, hnd->query, hnd->uploadDir); JS_ResumeRequest(cx, depth); *rval = retval ? JSVAL_TRUE : JSVAL_FALSE; for (n = hnd->query->head; n; n = n->next) { /* temporary fix? we don't want to overwrite our module readQuery() member */ if (!n->entry.name || !strcmp(n->entry.name,"readQuery")) continue; if (n->entry.value == NULL) n->entry.value = strdup(""); /* Match eekim's horrible semantics */ /* later optimization note: almost all of the cases where we'd need to * create arrays instead of strings are also cases where the CGI * variables of the same name are adjacent in the query */ if ((JS_GetProperty(cx, obj, n->entry.name, &val) == JS_TRUE) && (!JSVAL_IS_VOID(val))) { /* Already seen a CGI variable with this name */ if (JSVAL_IS_STRING(val)) /* Only seen one, create a new array */ { argv[0] = val; argv[1] = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, n->entry.value)); argv[0] = OBJECT_TO_JSVAL(JS_NewArrayObject(cx, 2, argv)); if (JS_SetProperty(cx, obj, n->entry.name, argv + 0) == JS_FALSE) return gpsee_throw(cx, OBJECT_ID ".readQuery.property.recreate.%s", n->entry.name); } else { jsuint length; /* seen many: append to the array */ if (JS_IsArrayObject(cx, JSVAL_TO_OBJECT(val)) != JS_TRUE) return gpsee_throw(cx, OBJECT_ID ".readQuery.property.type.%s", n->entry.name); if (JS_GetArrayLength(cx, JSVAL_TO_OBJECT(val), &length) != JS_TRUE) return gpsee_throw(cx, OBJECT_ID ".readQuery.property.%s.length.get", n->entry.name); if (JS_DefineElement(cx, JSVAL_TO_OBJECT(val), length, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, n->entry.value)), JS_PropertyStub, JS_PropertyStub, JSPROP_ENUMERATE) != JS_TRUE) return gpsee_throw(cx, OBJECT_ID ".readQuery.property.%s.element.%u", n->entry.name, length); if (JS_SetArrayLength(cx, JSVAL_TO_OBJECT(val), length + 1) != JS_TRUE) return gpsee_throw(cx, OBJECT_ID ".readQuery.property.%s.length.set", n->entry.name); } } else { /* First time for this property, insert it as a string */ argv[0] = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, n->entry.value)); if (JS_SetProperty(cx, obj, n->entry.name, argv + 0) == JS_FALSE) return gpsee_throw(cx, OBJECT_ID ".readQuery.property.create.%s", n->entry.name); } } return JS_TRUE; }
JavaPackage_resolve(JSContext *cx, JSObject *obj, jsval id) { JavaPackage_Private *package; JSBool ok = JS_TRUE; jclass jclazz; char *subPath, *newPath; const char *path; JNIEnv *jEnv; JSJavaThreadState *jsj_env; /* Painful hack for pre_define_java_packages() */ if (quiet_resolve_failure) return JS_FALSE; package = (JavaPackage_Private *)JS_GetPrivate(cx, obj); if (!package) return JS_TRUE; if (!JSVAL_IS_STRING(id)) return JS_TRUE; subPath = JS_GetStringBytes(JSVAL_TO_STRING(id)); /* * There will be an attempt to invoke the toString() method when producing * the string representation of a JavaPackage. When this occurs, avoid * creating a bogus toString package. (This means that no one can ever * create a package with the simple name "toString", but we'll live with * that limitation.) */ if (!strcmp(subPath, "toString")) return JS_FALSE; path = package->path; newPath = JS_smprintf("%s%s%s", path, (path[0] ? "/" : ""), subPath); if (!newPath) { JS_ReportOutOfMemory(cx); return JS_FALSE; } jsj_env = jsj_EnterJava(cx, &jEnv); if (!jEnv) { ok = JS_FALSE; goto out; } /* Unfortunately, Java provides no way to find out whether a particular name is a package or not. The only way to tell is to try to load the name as a class file and, if that fails, assume it's a package. This makes things work as expected for the most part, but it has three noticeable problems that keep coming up: - You can refer to a package like java.lang.i.buried.paul without generating a complaint. Of course, you'll never be able to refer to any classes through it. - An annoying consequence of the above is that misspelling a class name results in a cryptic error about packages. - In a browser context, i.e. where applets are involved, figuring out whether something is a class may require looking for it over the net using the current classloader. This means that the first time you refer to java.lang.System in a js context, there will be an attempt to search for [[DOCBASE]]/java.class on the server. A solution is to explicitly tell jsjava the names of all the (local) packages on the CLASSPATH. (Not implemented yet.) */ jclazz = (*jEnv)->FindClass(jEnv, newPath); if (jclazz) { JSObject *newClass; newClass = jsj_define_JavaClass(cx, jEnv, obj, subPath, jclazz); (*jEnv)->DeleteLocalRef(jEnv, jclazz); if (!newClass) { ok = JS_FALSE; goto out; } } else { /* We assume that any failed attempt to load a class is because it doesn't exist. If we wanted to do a better job, we would check the exception type and make sure that it's NoClassDefFoundError */ (*jEnv)->ExceptionClear(jEnv); /* * If there's no class of the given name, then we must be referring to * a package. However, don't allow bogus sub-packages of pre-defined * system packages to be created. */ if (JS_InstanceOf(cx, obj, &JavaPackage_class, NULL)) { JavaPackage_Private *current_package; current_package = JS_GetPrivate(cx, obj); if (current_package->flags & PKG_SYSTEM) { char *msg, *cp; msg = JS_strdup(cx, newPath); /* Check for OOM */ if (msg) { /* Convert package of form "java/lang" to "java.lang" */ for (cp = msg; *cp != '\0'; cp++) if (*cp == '/') *cp = '.'; JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, JSJMSG_MISSING_PACKAGE, msg); free((char*)msg); } ok = JS_FALSE; goto out; } } if (!define_JavaPackage(cx, obj, subPath, newPath, 0, JSPROP_READONLY)) { ok = JS_FALSE; goto out; } #ifdef DEBUG /* printf("JavaPackage \'%s\' created\n", newPath); */ #endif } out: free(newPath); jsj_ExitJava(jsj_env); return ok; }
url_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { jsval slot; JSURL *url; JSString * str; char *port; const char *cstr, *tmp; if (!JSVAL_IS_INT(id)) return JS_TRUE; slot = JSVAL_TO_INT(id); url = JS_GetInstancePrivate(cx, obj, &lm_url_class, NULL); if (!url) { url = JS_GetInstancePrivate(cx, obj, &lm_location_class, NULL); if (!url) return JS_TRUE; } str = 0; cstr = 0; switch (slot) { case URL_HREF: str = url->href; break; case URL_PROTOCOL: if (url->href) cstr = ParseURL(JS_GetStringBytes(url->href), GET_PROTOCOL_PART); break; case URL_HOST: if (url->href) cstr = ParseURL(JS_GetStringBytes(url->href), GET_HOST_PART); break; case URL_HOSTNAME: if (url->href) cstr = ParseURL(JS_GetStringBytes(url->href), GET_HOST_PART); if (cstr && (port = XP_STRCHR(cstr, ':')) != 0) *port = '\0'; break; case URL_PORT: if (url->href) cstr = ParseURL(JS_GetStringBytes(url->href), GET_HOST_PART); if (cstr && (port = XP_STRCHR(cstr, ':')) != 0) port++; else port = ""; tmp = cstr; cstr = JS_strdup(cx, port); XP_FREE((void *)tmp); break; case URL_PATHNAME: if (url->href) cstr = ParseURL(JS_GetStringBytes(url->href), GET_PATH_PART); break; case URL_HASH: if (url->href) cstr = ParseURL(JS_GetStringBytes(url->href), GET_HASH_PART); break; case URL_SEARCH: if (url->href) cstr = ParseURL(JS_GetStringBytes(url->href), GET_SEARCH_PART); break; case URL_TARGET: if (!url->target) { *vp = JSVAL_NULL; return JS_TRUE; } str = url->target; break; case URL_TEXT: if (!url->text) { *vp = JSVAL_NULL; return JS_TRUE; } str = url->text; break; case URL_X: case URL_Y: return url_get_coord(cx, url, slot, vp); default: /* Don't mess with user-defined or method properties. */ return JS_TRUE; } if (!str && cstr) str = JS_NewStringCopyZ(cx, cstr); if (cstr) XP_FREE((char *)cstr); if (!str) return JS_FALSE; *vp = STRING_TO_JSVAL(str); return JS_TRUE; }
const char * lm_CheckURL(JSContext *cx, const char *url_string, JSBool checkFile) { char *protocol, *absolute; JSObject *obj; MochaDecoder *decoder; protocol = NET_ParseURL(url_string, GET_PROTOCOL_PART); if (!protocol || *protocol == '\0') { lo_TopState *top_state; obj = JS_GetGlobalObject(cx); decoder = JS_GetPrivate(cx, obj); LO_LockLayout(); top_state = lo_GetMochaTopState(decoder->window_context); if (top_state && top_state->base_url) { absolute = NET_MakeAbsoluteURL(top_state->base_url, (char *)url_string); /*XXX*/ /* * Temporarily unlock layout so that we don't hold the lock * across a call (lm_CheckPermissions) that may result in * synchronous event handling. */ LO_UnlockLayout(); if (!lm_CheckPermissions(cx, obj, JSTARGET_UNIVERSAL_BROWSER_READ)) { /* Don't leak information about the url of this page. */ XP_FREEIF(absolute); return NULL; } LO_LockLayout(); } else { absolute = NULL; } if (absolute) { if (protocol) XP_FREE(protocol); protocol = NET_ParseURL(absolute, GET_PROTOCOL_PART); } LO_UnlockLayout(); } else { absolute = JS_strdup(cx, url_string); if (!absolute) { XP_FREE(protocol); return NULL; } decoder = NULL; } if (absolute) { /* Make sure it's a safe URL type. */ switch (NET_URL_Type(protocol)) { case FILE_TYPE_URL: if (checkFile) { const char *subjectOrigin = lm_GetSubjectOriginURL(cx); if (subjectOrigin == NULL) { XP_FREE(protocol); return NULL; } if (NET_URL_Type(subjectOrigin) != FILE_TYPE_URL && !lm_CanAccessTarget(cx, JSTARGET_UNIVERSAL_FILE_READ)) { XP_FREE(absolute); absolute = NULL; } } break; case FTP_TYPE_URL: case GOPHER_TYPE_URL: case HTTP_TYPE_URL: case MAILTO_TYPE_URL: case NEWS_TYPE_URL: case RLOGIN_TYPE_URL: case TELNET_TYPE_URL: case TN3270_TYPE_URL: case WAIS_TYPE_URL: case SECURE_HTTP_TYPE_URL: case URN_TYPE_URL: case NFS_TYPE_URL: case MOCHA_TYPE_URL: case VIEW_SOURCE_TYPE_URL: case NETHELP_TYPE_URL: case WYSIWYG_TYPE_URL: case LDAP_TYPE_URL: #ifdef JAVA case MARIMBA_TYPE_URL: #endif /* These are "safe". */ break; case ABOUT_TYPE_URL: if (XP_STRCASECMP(absolute, "about:blank") == 0) break; if (XP_STRNCASECMP(absolute, "about:pics", 10) == 0) break; /* these are OK if we are signed */ if (lm_CanAccessTarget(cx, JSTARGET_UNIVERSAL_BROWSER_READ)) break; /* FALL THROUGH */ default: /* All others are naughty. */ XP_FREE(absolute); absolute = NULL; break; } } if (!absolute) { JS_ReportError(cx, "illegal URL method '%s'", protocol && *protocol ? protocol : url_string); } if (protocol) XP_FREE(protocol); return absolute; }