static JSBool sendreq(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval) { HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj); char* body = NULL; size_t bodylen = 0; JSBool ret = JS_FALSE; if(!http) { JS_ReportError(cx, "Invalid CouchHTTP instance."); goto done; } if(argv[0] != JSVAL_VOID && argv[0] != JS_GetEmptyStringValue(cx)) { body = enc_string(cx, argv[0], &bodylen); if(!body) { JS_ReportError(cx, "Failed to encode body."); goto done; } } ret = go(cx, obj, http, body, bodylen); done: if(body) free(body); return ret; }
JSBool Output_initialize (JSContext* cx) { JSBool result = JS_FALSE; JS_BeginRequest(cx); JS_EnterLocalRootScope(cx); jsval property; JSObject* output = JS_DefineObject(cx, ((LCGIData*) JS_GetContextPrivate(cx))->global, "Output", &Output_class, NULL, 0 ); if (output) { property = INT_TO_JSVAL(1024); JS_SetProperty(cx, output, "limit", &property); property = JSVAL_FALSE; JS_SetProperty(cx, output, "buffered", &property); property = JS_GetEmptyStringValue(cx); JS_SetProperty(cx, output, "content", &property); result = JS_TRUE; } JS_LeaveLocalRootScope(cx); JS_EndRequest(cx); return result; }
// convert a readable to a JSString, copying string data // static jsval XPCStringConvert::ReadableToJSVal(JSContext *cx, const nsAString &readable, nsStringBuffer** sharedBuffer) { JSString *str; *sharedBuffer = nullptr; uint32_t length = readable.Length(); if (length == 0) return JS_GetEmptyStringValue(cx); nsStringBuffer *buf = nsStringBuffer::FromString(readable); if (buf) { if (buf == sCachedBuffer && js::GetGCThingCompartment(sCachedString) == js::GetContextCompartment(cx)) { // We're done. Just return our existing string. return JS::StringValue(sCachedString); } // yay, we can share the string's buffer! str = JS_NewExternalString(cx, reinterpret_cast<jschar *>(buf->Data()), length, &sDOMStringFinalizer); if (str) { *sharedBuffer = buf; sCachedString = str; sCachedBuffer = buf; } } else { // blech, have to copy. jschar *chars = reinterpret_cast<jschar *> (JS_malloc(cx, (length + 1) * sizeof(jschar))); if (!chars) return JSVAL_NULL; if (length && !CopyUnicodeTo(readable, 0, reinterpret_cast<PRUnichar *>(chars), length)) { JS_free(cx, chars); return JSVAL_NULL; } chars[length] = 0; str = JS_NewUCString(cx, chars, length); if (!str) JS_free(cx, chars); } return str ? STRING_TO_JSVAL(str) : JSVAL_NULL; }
void FFSessionHandler::getStringObjectClass(JSContext* ctx) { jsval str = JS_GetEmptyStringValue(ctx); JSObject* obj = 0; if (!JS_ValueToObject(ctx, str, &obj)) { return; } if (!obj) { return; } stringObjectClass = JS_GET_CLASS(ctx, obj); }
// **************************************************************************** // *** static helper functions // **************************************************************************** JSBool GetValue(JSContext *cx, JSObject *obj, int index, jsval *ret) { gstRecordJSWrapperImpl* wrapper = static_cast<gstRecordJSWrapperImpl*>(JS_GetPrivate(cx, obj)); if (!wrapper) { JS_ReportError(cx, "object doesn't have gstRecordWrapper\n"); return JS_FALSE; } const gstHeaderHandle &header = wrapper->header(); const gstRecordHandle &rec = wrapper->record(); if (!rec) { JS_ReportError(cx, "gstRecordWrapper doesn't have an active record"); return JS_FALSE; } if ((index >= 0) && (index < (int)header->numColumns())) { switch (header->ftype(index)) { case gstTagBoolean: *ret = BOOLEAN_TO_JSVAL(rec->Field(index)->ValueAsBoolean()); return JS_TRUE; case gstTagInt: case gstTagUInt: case gstTagInt64: case gstTagUInt64: case gstTagFloat: case gstTagDouble: return JS_NewNumberValue(cx, rec->Field(index)->ValueAsDouble(), ret); case gstTagString: case gstTagUnicode: { QString str = rec->Field(index)->ValueAsUnicode(); if (str.isEmpty()) { *ret = JS_GetEmptyStringValue(cx); } else { JSString *newstr = JS_NewUCStringCopyN(cx, str.ucs2(), str.length()); if (!newstr) { // out of memory error already reported return JS_FALSE; } *ret = STRING_TO_JSVAL(newstr); } return JS_TRUE; } default: JS_ReportError(cx, "Unhandled field type: %d", header->ftype(index)); } } else { JS_ReportError(cx, "field index out of range: %d", index); } return JS_FALSE; }
// convert a readable to a JSString, copying string data // static jsval XPCStringConvert::ReadableToJSVal(JSContext *cx, const nsAString &readable, nsStringBuffer** sharedBuffer) { JSString *str; *sharedBuffer = nullptr; uint32_t length = readable.Length(); if (length == 0) return JS_GetEmptyStringValue(cx); nsStringBuffer *buf = nsStringBuffer::FromString(readable); if (buf) { JS::RootedValue val(cx); bool shared; bool ok = StringBufferToJSVal(cx, buf, length, &val, &shared); if (!ok) { return JS::NullValue(); } if (shared) { *sharedBuffer = buf; } return val; } // blech, have to copy. jschar *chars = reinterpret_cast<jschar *> (JS_malloc(cx, (length + 1) * sizeof(jschar))); if (!chars) return JS::NullValue(); if (length && !CopyUnicodeTo(readable, 0, reinterpret_cast<PRUnichar *>(chars), length)) { JS_free(cx, chars); return JS::NullValue(); } chars[length] = 0; str = JS_NewUCString(cx, chars, length); if (!str) { JS_free(cx, chars); } return str ? STRING_TO_JSVAL(str) : JSVAL_NULL; }
JSString* couch_readline(JSContext* cx, FILE* fp) { JSString* str; char* bytes = NULL; char* tmp = NULL; size_t used = 0; size_t byteslen = 256; size_t readlen = 0; bytes = JS_malloc(cx, byteslen); if(bytes == NULL) return NULL; while((readlen = couch_fgets(bytes+used, byteslen-used, fp)) > 0) { used += readlen; if(bytes[used-1] == '\n') { bytes[used-1] = '\0'; break; } // Double our buffer and read more. byteslen *= 2; tmp = JS_realloc(cx, bytes, byteslen); if(!tmp) { JS_free(cx, bytes); return NULL; } bytes = tmp; } // Treat empty strings specially if(used == 0) { JS_free(cx, bytes); return JSVAL_TO_STRING(JS_GetEmptyStringValue(cx)); } // Shring the buffer to the actual data size tmp = JS_realloc(cx, bytes, used); if(!tmp) { JS_free(cx, bytes); return NULL; } bytes = tmp; byteslen = used; str = dec_string(cx, bytes, byteslen); JS_free(cx, bytes); return str; }
loc_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { JSURL *url; MochaDecoder *decoder; MWContext *context; const char *url_string; JSString *str; if (!JSVAL_IS_INT(id) || JSVAL_TO_INT(id) < 0) return JS_TRUE; url = JS_GetInstancePrivate(cx, obj, &lm_location_class, NULL); if (!url) return JS_TRUE; decoder = url->url_decoder; context = decoder->window_context; if (!context) return JS_TRUE; if (context->type == MWContextMail || context->type == MWContextNews || context->type == MWContextMailMsg || context->type == MWContextNewsMsg) { /* * Don't give out the location of a the mail folder to a script * embedded in a mail message. Just return the empty string. */ url->href = JSVAL_TO_STRING(JS_GetEmptyStringValue(cx)); } else { /* * Only need to check permissions for native getters */ if (!lm_CheckPermissions(cx, obj, JSTARGET_UNIVERSAL_BROWSER_READ)) return JS_FALSE; url_string = get_url_string(cx, obj); if (url_string && (!url->href || XP_STRCMP(JS_GetStringBytes(url->href), url_string) != 0)) { str = JS_NewStringCopyZ(cx, url_string); if (!str) return JS_FALSE; url->href = str; } } return url_getProperty(cx, obj, id, vp); }
JSBool Output_flush (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { JS_BeginRequest(cx); JS_EnterLocalRootScope(cx); jsval property; JS_GetProperty(cx, obj, "content", &property); FCGX_PutS(JS_GetStringBytes(JS_ValueToString(cx, property)), ((LCGIData*) JS_GetContextPrivate(cx))->cgi->out); property = JS_GetEmptyStringValue(cx); JS_SetProperty(cx, obj, "content", &property); JS_LeaveLocalRootScope(cx); JS_EndRequest(cx); return JS_TRUE; }
static JSBool navigator_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { FILE *fOut; JSString *str; size_t n, i; jschar *s; CMNavigator* cmNav = JS_GetInstancePrivate(cx, obj, &navigator_class, NULL); if (JSVAL_IS_INT(id)) { switch (JSVAL_TO_INT(id)) { case navigator_appversion: *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, cmNav->appVersion)); break; default: *vp = JS_GetEmptyStringValue(cx); } } return JS_TRUE; }
JSBool Output_content_set (JSContext *cx, JSObject *obj, jsval idval, jsval *vp) { JS_BeginRequest(cx); JS_EnterLocalRootScope(cx); jsval property; int limit; JSBool buffered; JSString* string; JS_GetProperty(cx, obj, "limit", &property); JS_ValueToInt32(cx, property, &limit); JS_GetProperty(cx, obj, "buffered", &property); JS_ValueToBoolean(cx, property, &buffered); string = JS_ValueToString(cx, *vp); if (!buffered && JS_GetStringLength(string) > limit) { if (!JSVAL_TO_BOOLEAN(JS_EVAL(cx, "Headers.sent"))) { JS_EVAL(cx, "Headers.send()"); } FCGX_Stream* out = ((LCGIData*) JS_GetContextPrivate(cx))->cgi->out; char* cString = JS_GetStringBytes(string); char size[300] = {NULL}; sprintf(size, "%x", strlen(cString)); FCGX_FPrintF(out, "%s\r\n%s\r\n", size, cString); property = JS_GetEmptyStringValue(cx); JS_SetProperty(cx, obj, "content", &property); } JS_LeaveLocalRootScope(cx); JS_EndRequest(cx); return JS_TRUE; }
component_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { JSComponent *component; JSString *str; jsint slot; if (!JSVAL_IS_INT(id)) return JS_TRUE; slot = JSVAL_TO_INT(id); component = JS_GetInstancePrivate(cx, obj, &lm_component_class, NULL); if (!component) return JS_TRUE; switch (slot) { case COMPONENT_NAME: str = component->name; if (str) *vp = STRING_TO_JSVAL(str); else *vp = JS_GetEmptyStringValue(cx); break; case COMPONENT_ACTIVE: *vp = JSVAL_FALSE; if (ET_moz_CallFunctionBool((ETBoolPtrFunc)component->active_callback, NULL)) *vp = JSVAL_TRUE; break; default: break; } return JS_TRUE; }
/* * function readline() * Provides a hook for scripts to read a line from stdin. */ static JSBool ReadLine(JSContext *cx, uintN argc, jsval *vp) { #define BUFSIZE 256 FILE *from; char *buf, *tmp; size_t bufsize, buflength, gotlength; JSBool sawNewline; JSString *str; SG_UNUSED(argc); from = stdin; buflength = 0; bufsize = BUFSIZE; buf = (char *) JS_malloc(cx, bufsize); if (!buf) return JS_FALSE; sawNewline = JS_FALSE; while ((gotlength = js_fgets(buf + buflength, (int)(bufsize - buflength), from)) > 0) { buflength += gotlength; /* Are we done? */ if (buf[buflength - 1] == '\n') { buf[buflength - 1] = '\0'; sawNewline = JS_TRUE; break; } else if (buflength < bufsize - 1) { break; } /* Else, grow our buffer for another pass. */ bufsize *= 2; if (bufsize > buflength) { tmp = (char *) JS_realloc(cx, buf, bufsize); } else { JS_ReportOutOfMemory(cx); tmp = NULL; } if (!tmp) { JS_free(cx, buf); return JS_FALSE; } buf = tmp; } /* Treat the empty string specially. */ if (buflength == 0) { *vp = feof(from) ? JSVAL_NULL : JS_GetEmptyStringValue(cx); JS_free(cx, buf); return JS_TRUE; } /* Shrink the buffer to the real size. */ tmp = (char *) JS_realloc(cx, buf, buflength); if (!tmp) { JS_free(cx, buf); return JS_FALSE; } buf = tmp; /* * Turn buf into a JSString. Note that buflength includes the trailing null * character. */ str = JS_NewStringCopyN(cx, buf, sawNewline ? buflength - 1 : buflength); JS_free(cx, buf); if (!str) return JS_FALSE; *vp = STRING_TO_JSVAL(str); return JS_TRUE; }
static JSBool array_join_sub(JSContext *cx, JSObject *obj, JSString *sep, JSBool literalize, jsval *rval, JSBool localeString) { JSBool ok; jsval v; jsuint length, index; jschar *chars, *ochars; size_t nchars, growth, seplen, tmplen; const jschar *sepstr; JSString *str; JSHashEntry *he; JSObject *obj2; ok = js_GetLengthProperty(cx, obj, &length); if (!ok) return JS_FALSE; he = js_EnterSharpObject(cx, obj, NULL, &chars); if (!he) return JS_FALSE; if (literalize) { if (IS_SHARP(he)) { #if JS_HAS_SHARP_VARS nchars = js_strlen(chars); #else chars[0] = '['; chars[1] = ']'; chars[2] = 0; nchars = 2; #endif goto make_string; } /* * Allocate 1 + 3 + 1 for "[", the worst-case closing ", ]", and the * terminating 0. */ growth = (1 + 3 + 1) * sizeof(jschar); if (!chars) { nchars = 0; chars = (jschar *) malloc(growth); if (!chars) goto done; } else { MAKE_SHARP(he); nchars = js_strlen(chars); chars = (jschar *) realloc((ochars = chars), nchars * sizeof(jschar) + growth); if (!chars) { free(ochars); goto done; } } chars[nchars++] = '['; } else { /* * Free any sharp variable definition in chars. Normally, we would * MAKE_SHARP(he) so that only the first sharp variable annotation is * a definition, and all the rest are references, but in the current * case of (!literalize), we don't need chars at all. */ if (chars) JS_free(cx, chars); chars = NULL; nchars = 0; /* Return the empty string on a cycle as well as on empty join. */ if (IS_BUSY(he) || length == 0) { js_LeaveSharpObject(cx, NULL); *rval = JS_GetEmptyStringValue(cx); return ok; } /* Flag he as BUSY so we can distinguish a cycle from a join-point. */ MAKE_BUSY(he); } sepstr = NULL; seplen = JSSTRING_LENGTH(sep); v = JSVAL_NULL; for (index = 0; index < length; index++) { ok = JS_GetElement(cx, obj, index, &v); if (!ok) goto done; if (!literalize && (JSVAL_IS_VOID(v) || JSVAL_IS_NULL(v))) { str = cx->runtime->emptyString; } else { if (localeString) { if (!js_ValueToObject(cx, v, &obj2) || !js_TryMethod(cx, obj2, cx->runtime->atomState.toLocaleStringAtom, 0, NULL, &v)) { str = NULL; } else { str = js_ValueToString(cx, v); } } else { str = (literalize ? js_ValueToSource : js_ValueToString)(cx, v); } if (!str) { ok = JS_FALSE; goto done; } } /* Allocate 3 + 1 at end for ", ", closing bracket, and zero. */ growth = (nchars + (sepstr ? seplen : 0) + JSSTRING_LENGTH(str) + 3 + 1) * sizeof(jschar); if (!chars) { chars = (jschar *) malloc(growth); if (!chars) goto done; } else { chars = (jschar *) realloc((ochars = chars), growth); if (!chars) { free(ochars); goto done; } } if (sepstr) { js_strncpy(&chars[nchars], sepstr, seplen); nchars += seplen; } sepstr = JSSTRING_CHARS(sep); tmplen = JSSTRING_LENGTH(str); js_strncpy(&chars[nchars], JSSTRING_CHARS(str), tmplen); nchars += tmplen; } done: if (literalize) { if (chars) { if (JSVAL_IS_VOID(v)) { chars[nchars++] = ','; chars[nchars++] = ' '; } chars[nchars++] = ']'; } } else { CLEAR_BUSY(he); } js_LeaveSharpObject(cx, NULL); if (!ok) { if (chars) free(chars); return ok; } make_string: if (!chars) { JS_ReportOutOfMemory(cx); return JS_FALSE; } chars[nchars] = 0; str = js_NewString(cx, chars, nchars, 0); if (!str) { free(chars); return JS_FALSE; } *rval = STRING_TO_JSVAL(str); return JS_TRUE; }
static JSBool go(JSContext* cx, JSObject* obj, HTTPData* http, char* body, size_t bodylen) { CurlState state; char* referer; JSString* jsbody; JSBool ret = JS_FALSE; jsval tmp; state.cx = cx; state.http = http; state.sendbuf = body; state.sendlen = bodylen; state.sent = 0; state.sent_once = 0; state.recvbuf = NULL; state.recvlen = 0; state.read = 0; if(HTTP_HANDLE == NULL) { HTTP_HANDLE = curl_easy_init(); curl_easy_setopt(HTTP_HANDLE, CURLOPT_READFUNCTION, send_body); curl_easy_setopt(HTTP_HANDLE, CURLOPT_SEEKFUNCTION, (curl_seek_callback) seek_body); curl_easy_setopt(HTTP_HANDLE, CURLOPT_HEADERFUNCTION, recv_header); curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEFUNCTION, recv_body); curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOPROGRESS, 1); curl_easy_setopt(HTTP_HANDLE, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); curl_easy_setopt(HTTP_HANDLE, CURLOPT_ERRORBUFFER, ERRBUF); curl_easy_setopt(HTTP_HANDLE, CURLOPT_COOKIEFILE, ""); curl_easy_setopt(HTTP_HANDLE, CURLOPT_USERAGENT, "CouchHTTP Client - Relax"); } if(!HTTP_HANDLE) { JS_ReportError(cx, "Failed to initialize cURL handle."); goto done; } if(!JS_GetReservedSlot(cx, obj, 0, &tmp)) { JS_ReportError(cx, "Failed to readreserved slot."); goto done; } if(!(referer = enc_string(cx, tmp, NULL))) { JS_ReportError(cx, "Failed to encode referer."); goto done; } curl_easy_setopt(HTTP_HANDLE, CURLOPT_REFERER, referer); free(referer); if(http->method < 0 || http->method > OPTIONS) { JS_ReportError(cx, "INTERNAL: Unknown method."); goto done; } curl_easy_setopt(HTTP_HANDLE, CURLOPT_CUSTOMREQUEST, METHODS[http->method]); curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOBODY, 0); curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 0); if(http->method == HEAD) { curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOBODY, 1); curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 0); } else if(http->method == POST || http->method == PUT) { curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 1); curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 0); } if(body && bodylen) { curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, bodylen); } else { curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, 0); } // curl_easy_setopt(HTTP_HANDLE, CURLOPT_VERBOSE, 1); curl_easy_setopt(HTTP_HANDLE, CURLOPT_URL, http->url); curl_easy_setopt(HTTP_HANDLE, CURLOPT_HTTPHEADER, http->req_headers); curl_easy_setopt(HTTP_HANDLE, CURLOPT_READDATA, &state); curl_easy_setopt(HTTP_HANDLE, CURLOPT_SEEKDATA, &state); curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEHEADER, &state); curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEDATA, &state); if(curl_easy_perform(HTTP_HANDLE) != 0) { JS_ReportError(cx, "Failed to execute HTTP request: %s", ERRBUF); goto done; } if(!state.resp_headers) { JS_ReportError(cx, "Failed to recieve HTTP headers."); goto done; } tmp = OBJECT_TO_JSVAL(state.resp_headers); if(!JS_DefineProperty( cx, obj, "_headers", tmp, NULL, NULL, JSPROP_READONLY )) { JS_ReportError(cx, "INTERNAL: Failed to set response headers."); goto done; } if(state.recvbuf) { state.recvbuf[state.read] = '\0'; jsbody = dec_string(cx, state.recvbuf, state.read+1); if(!jsbody) { // If we can't decode the body as UTF-8 we forcefully // convert it to a string by just forcing each byte // to a jschar. jsbody = str_from_binary(cx, state.recvbuf, state.read); if(!jsbody) { if(!JS_IsExceptionPending(cx)) { JS_ReportError(cx, "INTERNAL: Failed to decode body."); } goto done; } } tmp = STRING_TO_JSVAL(jsbody); } else { tmp = JS_GetEmptyStringValue(cx); } if(!JS_DefineProperty( cx, obj, "responseText", tmp, NULL, NULL, JSPROP_READONLY )) { JS_ReportError(cx, "INTERNAL: Failed to set responseText."); goto done; } ret = JS_TRUE; done: if(state.recvbuf) JS_free(cx, state.recvbuf); return ret; }