Пример #1
0
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;
}
Пример #2
0
  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;
  }
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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);
}
Пример #6
0
/*
 * 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;
}
Пример #7
0
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);
}
Пример #8
0
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);
}
Пример #9
0
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;
}
Пример #10
0
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;
}
Пример #11
0
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
}
Пример #12
0
/**
 *  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;
}
Пример #13
0
/*
 * 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;
                }
            }
        }
Пример #14
0
/*
 * 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;
}
Пример #15
0
/** 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;
}
Пример #16
0
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;
}
Пример #17
0
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;
}
Пример #18
0
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;
}