event_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { JSEvent *event; JSString *str; char ** urlArray; jsval urlVal; JSObject *array; jsint slot; if (!JSVAL_IS_INT(id)) return JS_TRUE; event = JS_GetInstancePrivate(cx, obj, &lm_event_class, NULL); if (!event) return JS_TRUE; if (!JSVAL_IS_INT(id)) return JS_TRUE; /* * You might think the following would make a real nice * switch() statement. But if you make it into one be * ready to battle the Win16 internal compiler error * demons. */ if (JSVAL_TO_INT(id) == EVENT_TYPE) { str = JS_NewStringCopyZ(cx, lm_EventName(event->type)); if (!str) return JS_FALSE; *vp = STRING_TO_JSVAL(str); } else if ((JSVAL_TO_INT(id) == EVENT_X) || (JSVAL_TO_INT(id) == EVENT_LAYERX)) { * vp = INT_TO_JSVAL(event->x); } else if ((JSVAL_TO_INT(id) == EVENT_Y) || (JSVAL_TO_INT(id) == EVENT_LAYERY)){ * vp = INT_TO_JSVAL(event->y); } else if (JSVAL_TO_INT(id) == EVENT_DOCX) { * vp = INT_TO_JSVAL(event->docx); } else if (JSVAL_TO_INT(id) == EVENT_DOCY) { * vp = INT_TO_JSVAL(event->docy); } else if (JSVAL_TO_INT(id) == EVENT_SCREENX) { * vp = INT_TO_JSVAL(event->screenx); } else if (JSVAL_TO_INT(id) == EVENT_SCREENY) { * vp = INT_TO_JSVAL(event->screeny); } else if (JSVAL_TO_INT(id) == EVENT_WHICH) { if (event->type == EVENT_HELP) { /* For onHelp events, the which parameter holds the URL of the help topic, as given in the pHelpInfo field of the MWContext associated with this window. */ MWContext *context; context = event->ce.context; if (context->pHelpInfo) { char *topicID; JSString *topicStr; topicID = ((HelpInfoStruct *) (context->pHelpInfo))->topicURL; topicStr = JS_NewStringCopyZ(cx, topicID); * vp = STRING_TO_JSVAL(topicStr); } else { JSString *topicStr; topicStr = JS_NewStringCopyZ(cx, "about:blank"); /* Do not localize */ * vp = STRING_TO_JSVAL(topicStr); } } else { * vp = INT_TO_JSVAL(event->which); } } else if (JSVAL_TO_INT(id) == EVENT_MODIFIERS) { * vp = INT_TO_JSVAL(event->modifiers); } else if (JSVAL_TO_INT(id) == EVENT_OBJECT) { if (event->object) * vp = OBJECT_TO_JSVAL(event->object); } else if (JSVAL_TO_INT(id) == EVENT_DATA) { if (event->type == EVENT_DRAGDROP) { if (lm_CanAccessTarget(cx, JSTARGET_UNIVERSAL_BROWSER_READ)) { array = JS_NewArrayObject(cx, 0, NULL); if (!array) return JS_FALSE; urlArray = (char**)event->data; if (!urlArray) return JS_TRUE; for (slot=0; slot<(jsint)event->dataSize; slot++) { str = JS_NewStringCopyZ(cx, urlArray[slot]); if (!str) return JS_FALSE; urlVal = STRING_TO_JSVAL(str); if (!JS_SetElement(cx, array, slot, &urlVal)) return JS_FALSE; } *vp = OBJECT_TO_JSVAL(array); } } } 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; }