diff options
Diffstat (limited to 'src/couch/priv')
22 files changed, 0 insertions, 4558 deletions
diff --git a/src/couch/priv/couch_ejson_compare/couch_ejson_compare.c b/src/couch/priv/couch_ejson_compare/couch_ejson_compare.c deleted file mode 100644 index a4e9d1cfa..000000000 --- a/src/couch/priv/couch_ejson_compare/couch_ejson_compare.c +++ /dev/null @@ -1,603 +0,0 @@ -/** - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -#include <stdio.h> -#include <string.h> -#include <assert.h> -#include "erl_nif.h" -#include "unicode/ucol.h" -#include "unicode/ucasemap.h" - -#define MAX_DEPTH 10 - -#define NO_ERROR 0 -#define BAD_ARG_ERROR 1 -#define MAX_DEPTH_ERROR 2 - -#if (ERL_NIF_MAJOR_VERSION > 2) || \ - (ERL_NIF_MAJOR_VERSION == 2 && ERL_NIF_MINOR_VERSION >= 3) -/* OTP R15B or higher */ -#define term_is_number(env, t) enif_is_number(env, t) -#else -#define term_is_number(env, t) \ - (!enif_is_binary(env, t) && \ - !enif_is_list(env, t) && \ - !enif_is_tuple(env, t)) -#endif - -#ifdef _MSC_VER -#define threadlocal __declspec(thread) -#else -#define threadlocal __thread -#endif - -static ERL_NIF_TERM ATOM_TRUE; -static ERL_NIF_TERM ATOM_FALSE; -static ERL_NIF_TERM ATOM_NULL; -static ERL_NIF_TERM ATOM_MAX_DEPTH_ERROR; - -typedef struct { - ErlNifEnv* env; - int error; - UCollator* coll; -} ctx_t; - -static threadlocal UCollator* collator = NULL; -static threadlocal int64_t threadEpoch = 0; -static UCollator** collators = NULL; -static int numCollators = 0; -static int numSchedulers = 0; -static int64_t loadEpoch = 0; -static ErlNifMutex* collMutex = NULL; - -static ERL_NIF_TERM less_json_nif(ErlNifEnv*, int, const ERL_NIF_TERM []); -static ERL_NIF_TERM compare_strings_nif(ErlNifEnv*, int, const ERL_NIF_TERM []); -static ERL_NIF_TERM get_icu_version(ErlNifEnv*, int, const ERL_NIF_TERM []); -static ERL_NIF_TERM get_uca_version(ErlNifEnv*, int, const ERL_NIF_TERM []); -static ERL_NIF_TERM get_collator_version(ErlNifEnv*, int, const ERL_NIF_TERM []); -static int on_load(ErlNifEnv*, void**, ERL_NIF_TERM); -static void on_unload(ErlNifEnv*, void*); -static __inline int less_json(int, ctx_t*, ERL_NIF_TERM, ERL_NIF_TERM); -static __inline int atom_sort_order(ErlNifEnv*, ERL_NIF_TERM); -static __inline int compare_strings(ctx_t*, ErlNifBinary, ErlNifBinary); -static __inline int compare_lists(int, ctx_t*, ERL_NIF_TERM, ERL_NIF_TERM); -static __inline int compare_props(int, ctx_t*, ERL_NIF_TERM, ERL_NIF_TERM); -static __inline int is_max_utf8_marker(ErlNifBinary); -static __inline UCollator* get_collator(void); - -/* Should match the <<255,255,255,255>> in: - * - src/mango/src/mango_idx_view.hrl#L13 - * - src/couch_mrview/src/couch_mrview_util.erl#L40 */ -static const unsigned char max_utf8_marker[] = {255, 255, 255, 255}; - - -UCollator* -get_collator(void) -{ - UErrorCode status = U_ZERO_ERROR; - - if(collator != NULL && threadEpoch == loadEpoch) { - return collator; - } - - collator = ucol_open("", &status); - - if (U_FAILURE(status)) { - ucol_close(collator); - return NULL; - } - - enif_mutex_lock(collMutex); - collators[numCollators] = collator; - numCollators++; - enif_mutex_unlock(collMutex); - - assert(numCollators <= numSchedulers && "Number of schedulers shrank."); - - threadEpoch = loadEpoch; - - return collator; -} - -ERL_NIF_TERM -less_json_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{ - ctx_t ctx; - int result; - - ctx.env = env; - ctx.error = NO_ERROR; - ctx.coll = get_collator(); - - result = less_json(1, &ctx, argv[0], argv[1]); - - /* - * There are 2 possible failure reasons: - * - * 1) We got an invalid EJSON operand; - * 2) The EJSON structures are too deep - to avoid allocating too - * many C stack frames (because less_json is a recursive function), - * and running out of memory, we throw a badarg exception to Erlang - * and do the comparison in Erlang land. In practice, views keys are - * EJSON structures with very little nesting. - */ - if (ctx.error == NO_ERROR) { - return enif_make_int(env, result); - } else if (ctx.error == MAX_DEPTH_ERROR) { - return enif_raise_exception(env, ATOM_MAX_DEPTH_ERROR); - } else { - return enif_make_badarg(env); - } -} - - -ERL_NIF_TERM -compare_strings_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{ - ctx_t ctx; - int result; - ErlNifBinary binA, binB; - - if (!enif_inspect_binary(env, argv[0], &binA)) { - return enif_make_badarg(env); - } - - if (!enif_inspect_binary(env, argv[1], &binB)) { - return enif_make_badarg(env); - } - - ctx.env = env; - ctx.error = NO_ERROR; - ctx.coll = get_collator(); - - result = compare_strings(&ctx, binA, binB); - - if (ctx.error == NO_ERROR){ - return enif_make_int(env, result); - } else { - return enif_make_badarg(env); - } -} - - -ERL_NIF_TERM -get_icu_version(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{ - UVersionInfo ver = {0}; - ERL_NIF_TERM tup[U_MAX_VERSION_LENGTH] = {0}; - int i; - - u_getVersion(ver); - - for (i = 0; i < U_MAX_VERSION_LENGTH; i++) { - tup[i] = enif_make_int(env, ver[i]); - } - - return enif_make_tuple_from_array(env, tup, U_MAX_VERSION_LENGTH); -} - - -ERL_NIF_TERM -get_uca_version(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{ - UVersionInfo ver = {0}; - ERL_NIF_TERM tup[U_MAX_VERSION_LENGTH] = {0}; - int i; - - ucol_getUCAVersion(get_collator(), ver); - - for (i = 0; i < U_MAX_VERSION_LENGTH; i++) { - tup[i] = enif_make_int(env, ver[i]); - } - - return enif_make_tuple_from_array(env, tup, U_MAX_VERSION_LENGTH); -} - -ERL_NIF_TERM -get_collator_version(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{ - UVersionInfo ver = {0}; - ERL_NIF_TERM tup[U_MAX_VERSION_LENGTH] = {0}; - int i; - - ucol_getVersion(get_collator(), ver); - - for (i = 0; i < U_MAX_VERSION_LENGTH; i++) { - tup[i] = enif_make_int(env, ver[i]); - } - - return enif_make_tuple_from_array(env, tup, U_MAX_VERSION_LENGTH); -} - -int -less_json(int depth, ctx_t* ctx, ERL_NIF_TERM a, ERL_NIF_TERM b) -{ - int aIsAtom, bIsAtom; - int aIsBin, bIsBin; - int aIsNumber, bIsNumber; - int aIsList, bIsList; - int aArity, bArity; - int aIsProps, bIsProps; - const ERL_NIF_TERM *aProps, *bProps; - - /* - * Avoid too much recursion. Normally there isn't more than a few levels - * of recursion, as in practice view keys do not go beyond 1 to 3 levels - * of nesting. In case of too much recursion, signal it to the Erlang land - * via an exception and do the EJSON comparison in Erlang land. - */ - if (depth > MAX_DEPTH) { - ctx->error = MAX_DEPTH_ERROR; - return 0; - } - - aIsAtom = enif_is_atom(ctx->env, a); - bIsAtom = enif_is_atom(ctx->env, b); - - if (aIsAtom) { - if (bIsAtom) { - int aSortOrd, bSortOrd; - - if ((aSortOrd = atom_sort_order(ctx->env, a)) == -1) { - ctx->error = BAD_ARG_ERROR; - return 0; - } - - if ((bSortOrd = atom_sort_order(ctx->env, b)) == -1) { - ctx->error = BAD_ARG_ERROR; - return 0; - } - - return aSortOrd - bSortOrd; - } - - return -1; - } - - if (bIsAtom) { - return 1; - } - - aIsNumber = term_is_number(ctx->env, a); - bIsNumber = term_is_number(ctx->env, b); - - if (aIsNumber) { - if (bIsNumber) { - return enif_compare(a, b); - } - - return -1; - } - - if (bIsNumber) { - return 1; - } - - aIsBin = enif_is_binary(ctx->env, a); - bIsBin = enif_is_binary(ctx->env, b); - - if (aIsBin) { - if (bIsBin) { - ErlNifBinary binA, binB; - - enif_inspect_binary(ctx->env, a, &binA); - enif_inspect_binary(ctx->env, b, &binB); - - return compare_strings(ctx, binA, binB); - } - - return -1; - } - - if (bIsBin) { - return 1; - } - - aIsList = enif_is_list(ctx->env, a); - bIsList = enif_is_list(ctx->env, b); - - if (aIsList) { - if (bIsList) { - return compare_lists(depth, ctx, a, b); - } - - return -1; - } - - if (bIsList) { - return 1; - } - - - aIsProps = 0; - if (enif_get_tuple(ctx->env, a, &aArity, &aProps)) { - if (aArity == 1 && enif_is_list(ctx->env, aProps[0])) { - aIsProps = 1; - } - } - - bIsProps = 0; - if (enif_get_tuple(ctx->env, b, &bArity, &bProps)) { - if (bArity == 1 && enif_is_list(ctx->env, bProps[0])) { - bIsProps = 1; - } - } - - if (aIsProps) { - if (bIsProps) { - return compare_props(depth, ctx, aProps[0], bProps[0]); - } - return -1; - } - - if (bIsProps) { - return 1; - } - - /* - * Both arguments are unsupported data types. Return a badarg error - */ - ctx->error = BAD_ARG_ERROR; - return 0; -} - - -int -atom_sort_order(ErlNifEnv* env, ERL_NIF_TERM a) -{ - if (enif_compare(a, ATOM_NULL) == 0) { - return 1; - } else if (enif_compare(a, ATOM_FALSE) == 0) { - return 2; - } else if (enif_compare(a, ATOM_TRUE) == 0) { - return 3; - } - - return -1; -} - - -int -compare_lists(int depth, ctx_t* ctx, ERL_NIF_TERM a, ERL_NIF_TERM b) -{ - ERL_NIF_TERM headA, tailA; - ERL_NIF_TERM headB, tailB; - int aIsEmpty, bIsEmpty; - int result; - - while (1) { - aIsEmpty = !enif_get_list_cell(ctx->env, a, &headA, &tailA); - bIsEmpty = !enif_get_list_cell(ctx->env, b, &headB, &tailB); - - if (aIsEmpty) { - if (bIsEmpty) { - return 0; - } - return -1; - } - - if (bIsEmpty) { - return 1; - } - - result = less_json(depth + 1, ctx, headA, headB); - - if (ctx->error || result != 0) { - return result; - } - - a = tailA; - b = tailB; - } - - return result; -} - - -int -compare_props(int depth, ctx_t* ctx, ERL_NIF_TERM a, ERL_NIF_TERM b) -{ - ERL_NIF_TERM headA, tailA; - ERL_NIF_TERM headB, tailB; - int aArity, bArity; - const ERL_NIF_TERM *aKV, *bKV; - ErlNifBinary keyA, keyB; - int aIsEmpty, bIsEmpty; - int keyCompResult, valueCompResult; - - while (1) { - aIsEmpty = !enif_get_list_cell(ctx->env, a, &headA, &tailA); - bIsEmpty = !enif_get_list_cell(ctx->env, b, &headB, &tailB); - - if (aIsEmpty) { - if (bIsEmpty) { - return 0; - } - return -1; - } - - if (bIsEmpty) { - return 1; - } - - if (!enif_get_tuple(ctx->env, headA, &aArity, &aKV)) { - ctx->error = BAD_ARG_ERROR; - return 0; - } - if ((aArity != 2) || !enif_inspect_binary(ctx->env, aKV[0], &keyA)) { - ctx->error = BAD_ARG_ERROR; - return 0; - } - - if (!enif_get_tuple(ctx->env, headB, &bArity, &bKV)) { - ctx->error = BAD_ARG_ERROR; - return 0; - } - if ((bArity != 2) || !enif_inspect_binary(ctx->env, bKV[0], &keyB)) { - ctx->error = BAD_ARG_ERROR; - return 0; - } - - keyCompResult = compare_strings(ctx, keyA, keyB); - - if (ctx->error || keyCompResult != 0) { - return keyCompResult; - } - - valueCompResult = less_json(depth + 1, ctx, aKV[1], bKV[1]); - - if (ctx->error || valueCompResult != 0) { - return valueCompResult; - } - - a = tailA; - b = tailB; - } - - return 0; -} - - -int -is_max_utf8_marker(ErlNifBinary bin) -{ - if (bin.size == sizeof(max_utf8_marker)) { - if(memcmp(bin.data, max_utf8_marker, sizeof(max_utf8_marker)) == 0) { - return 1; - } - return 0; - } - return 0; -} - - -int -compare_strings(ctx_t* ctx, ErlNifBinary a, ErlNifBinary b) -{ - UErrorCode status = U_ZERO_ERROR; - UCharIterator iterA, iterB; - int result; - - /* libicu versions earlier than 59 (at least) don't consider the - * {255,255,255,255} to be the highest sortable string as CouchDB expects. - * While we are still shipping CentOS 7 packages with libicu 50, we should - * explicitly check for the marker, later on we can remove the max - * logic */ - - int a_is_max = is_max_utf8_marker(a); - int b_is_max = is_max_utf8_marker(b); - - if(a_is_max && b_is_max) { - return 0; - } - - if(a_is_max) { - return 1; - } - - if(b_is_max) { - return -1; - } - - uiter_setUTF8(&iterA, (const char *) a.data, (uint32_t) a.size); - uiter_setUTF8(&iterB, (const char *) b.data, (uint32_t) b.size); - - result = ucol_strcollIter(ctx->coll, &iterA, &iterB, &status); - - if (U_FAILURE(status)) { - ctx->error = BAD_ARG_ERROR; - return 0; - } - - /* ucol_strcollIter returns 0, -1 or 1 - * (see type UCollationResult in unicode/ucol.h) */ - - return result; -} - - -int -on_load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info) -{ - if (!enif_get_int(env, info, &numSchedulers)) { - return 1; - } - - if (numSchedulers < 1) { - return 2; - } - - loadEpoch += 1; - - collMutex = enif_mutex_create("coll_mutex"); - - if (collMutex == NULL) { - return 3; - } - - collators = enif_alloc(sizeof(UCollator*) * numSchedulers); - - if (collators == NULL) { - enif_mutex_destroy(collMutex); - return 4; - } - - ATOM_TRUE = enif_make_atom(env, "true"); - ATOM_FALSE = enif_make_atom(env, "false"); - ATOM_NULL = enif_make_atom(env, "null"); - ATOM_MAX_DEPTH_ERROR = enif_make_atom(env, "max_depth_error"); - - return 0; -} - - -void -on_unload(ErlNifEnv* env, void* priv_data) -{ - if (collators != NULL) { - int i; - - for (i = 0; i < numCollators; i++) { - ucol_close(collators[i]); - } - - enif_free(collators); - } - - numCollators = 0; - - if (collMutex != NULL) { - enif_mutex_destroy(collMutex); - } -} - - -static ErlNifFunc nif_functions[] = { - {"less_nif", 2, less_json_nif}, - {"compare_strings_nif", 2, compare_strings_nif}, - {"get_icu_version", 0, get_icu_version}, - {"get_uca_version", 0, get_uca_version}, - {"get_collator_version", 0, get_collator_version} -}; - - -#ifdef __cplusplus -extern "C" { -#endif - -ERL_NIF_INIT(couch_ejson_compare, nif_functions, &on_load, NULL, NULL, &on_unload); - -#ifdef __cplusplus -} -#endif diff --git a/src/couch/priv/couch_js/1.8.5/help.h b/src/couch/priv/couch_js/1.8.5/help.h deleted file mode 100644 index 3a19901f0..000000000 --- a/src/couch/priv/couch_js/1.8.5/help.h +++ /dev/null @@ -1,79 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. - -#ifndef COUCHJS_HELP_H -#define COUCHJS_HELP_H - -#include "config.h" - -static const char VERSION_TEMPLATE[] = - "%s - %s (SpiderMonkey 1.8.5)\n" - "\n" - "Licensed under the Apache License, Version 2.0 (the \"License\"); you may " - "not use\n" - "this file except in compliance with the License. You may obtain a copy of" - "the\n" - "License at\n" - "\n" - " http://www.apache.org/licenses/LICENSE-2.0\n" - "\n" - "Unless required by applicable law or agreed to in writing, software " - "distributed\n" - "under the License is distributed on an \"AS IS\" BASIS, WITHOUT " - "WARRANTIES OR\n" - "CONDITIONS OF ANY KIND, either express or implied. See the License " - "for the\n" - "specific language governing permissions and limitations under the " - "License.\n"; - -static const char USAGE_TEMPLATE[] = - "Usage: %s [FILE]\n" - "\n" - "The %s command runs the %s JavaScript interpreter.\n" - "\n" - "The exit status is 0 for success or 1 for failure.\n" - "\n" - "Options:\n" - "\n" - " -h display a short help message and exit\n" - " -V display version information and exit\n" - " -S SIZE specify that the runtime should allow at\n" - " most SIZE bytes of memory to be allocated\n" - " default is 64 MiB\n" - " --eval Enable runtime code evaluation (dangerous!)\n" - "\n" - "Report bugs at <%s>.\n"; - -#define BASENAME COUCHJS_NAME - -#define couch_version(basename) \ - fprintf( \ - stdout, \ - VERSION_TEMPLATE, \ - basename, \ - PACKAGE_STRING) - -#define DISPLAY_VERSION couch_version(BASENAME) - - -#define couch_usage(basename) \ - fprintf( \ - stdout, \ - USAGE_TEMPLATE, \ - basename, \ - basename, \ - PACKAGE_NAME, \ - PACKAGE_BUGREPORT) - -#define DISPLAY_USAGE couch_usage(BASENAME) - -#endif // Included help.h diff --git a/src/couch/priv/couch_js/1.8.5/main.c b/src/couch/priv/couch_js/1.8.5/main.c deleted file mode 100644 index c8e385cc9..000000000 --- a/src/couch/priv/couch_js/1.8.5/main.c +++ /dev/null @@ -1,307 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#ifdef XP_WIN -#include <windows.h> -#else -#include <unistd.h> -#endif - -#include <jsapi.h> -#include "config.h" -#include "utf8.h" -#include "util.h" - - -#define SETUP_REQUEST(cx) \ - JS_SetContextThread(cx); \ - JS_BeginRequest(cx); -#define FINISH_REQUEST(cx) \ - JS_EndRequest(cx); \ - JS_ClearContextThread(cx); - - -static JSClass global_class = { - "GlobalClass", - JSCLASS_GLOBAL_FLAGS, - JS_PropertyStub, - JS_PropertyStub, - JS_PropertyStub, - JS_StrictPropertyStub, - JS_EnumerateStub, - JS_ResolveStub, - JS_ConvertStub, - JS_FinalizeStub, - JSCLASS_NO_OPTIONAL_MEMBERS -}; - -static JSBool -evalcx(JSContext *cx, uintN argc, jsval* vp) -{ - jsval* argv = JS_ARGV(cx, vp); - JSString* str; - JSObject* sandbox; - JSObject* global; - JSContext* subcx; - JSCrossCompartmentCall* call = NULL; - const jschar* src; - size_t srclen; - jsval rval; - JSBool ret = JS_FALSE; - char *name = NULL; - - sandbox = NULL; - if(!JS_ConvertArguments(cx, argc, argv, "S / o", &str, &sandbox)) { - return JS_FALSE; - } - - subcx = JS_NewContext(JS_GetRuntime(cx), 8L * 1024L); - if(!subcx) { - JS_ReportOutOfMemory(cx); - return JS_FALSE; - } - - SETUP_REQUEST(subcx); - - src = JS_GetStringCharsAndLength(cx, str, &srclen); - - // Re-use the compartment associated with the main context, - // rather than creating a new compartment */ - global = JS_GetGlobalObject(cx); - if(global == NULL) goto done; - call = JS_EnterCrossCompartmentCall(subcx, global); - - if(!sandbox) { - sandbox = JS_NewGlobalObject(subcx, &global_class); - if(!sandbox || !JS_InitStandardClasses(subcx, sandbox)) { - goto done; - } - } - - if(argc > 2) { - name = enc_string(cx, argv[2], NULL); - } - - if(srclen == 0) { - JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(sandbox)); - } else { - JS_EvaluateUCScript(subcx, sandbox, src, srclen, name, 1, &rval); - JS_SET_RVAL(cx, vp, rval); - } - - ret = JS_TRUE; - -done: - if(name) JS_free(cx, name); - JS_LeaveCrossCompartmentCall(call); - FINISH_REQUEST(subcx); - JS_DestroyContext(subcx); - return ret; -} - - -static JSBool -gc(JSContext* cx, uintN argc, jsval* vp) -{ - JS_GC(cx); - JS_SET_RVAL(cx, vp, JSVAL_VOID); - return JS_TRUE; -} - - -static JSBool -print(JSContext* cx, uintN argc, jsval* vp) -{ - jsval* argv = JS_ARGV(cx, vp); - couch_print(cx, argc, argv); - JS_SET_RVAL(cx, vp, JSVAL_VOID); - return JS_TRUE; -} - - -static JSBool -quit(JSContext* cx, uintN argc, jsval* vp) -{ - jsval* argv = JS_ARGV(cx, vp); - int exit_code = 0; - JS_ConvertArguments(cx, argc, argv, "/i", &exit_code); - exit(exit_code); -} - - -static JSBool -readline(JSContext* cx, uintN argc, jsval* vp) -{ - JSString* line; - - /* GC Occasionally */ - JS_MaybeGC(cx); - - line = couch_readline(cx, stdin); - if(line == NULL) return JS_FALSE; - - JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(line)); - return JS_TRUE; -} - - -static JSBool -seal(JSContext* cx, uintN argc, jsval* vp) -{ - jsval* argv = JS_ARGV(cx, vp); - JSObject *target; - JSBool deep = JS_FALSE; - JSBool ret; - - if(!JS_ConvertArguments(cx, argc, argv, "o/b", &target, &deep)) - return JS_FALSE; - - if(!target) { - JS_SET_RVAL(cx, vp, JSVAL_VOID); - return JS_TRUE; - } - - - ret = deep ? JS_DeepFreezeObject(cx, target) : JS_FreezeObject(cx, target); - JS_SET_RVAL(cx, vp, JSVAL_VOID); - return ret; -} - - -static JSFunctionSpec global_functions[] = { - JS_FS("evalcx", evalcx, 0, 0), - JS_FS("gc", gc, 0, 0), - JS_FS("print", print, 0, 0), - JS_FS("quit", quit, 0, 0), - JS_FS("readline", readline, 0, 0), - JS_FS("seal", seal, 0, 0), - JS_FS_END -}; - - -static JSBool -csp_allows(JSContext* cx) -{ - couch_args *args = (couch_args*)JS_GetContextPrivate(cx); - if(args->eval) { - return JS_TRUE; - } else { - return JS_FALSE; - } -} - - -static JSSecurityCallbacks security_callbacks = { - NULL, - NULL, - NULL, - csp_allows -}; - - -int -main(int argc, const char* argv[]) -{ - JSRuntime* rt = NULL; - JSContext* cx = NULL; - JSObject* global = NULL; - JSCrossCompartmentCall *call = NULL; - JSSCRIPT_TYPE script; - JSString* scriptsrc; - const jschar* schars; - size_t slen; - jsval sroot; - jsval result; - int i; - - couch_args* args = couch_parse_args(argc, argv); - - rt = JS_NewRuntime(args->stack_size); - if(rt == NULL) - return 1; - - cx = JS_NewContext(rt, 8L * 1024L); - if(cx == NULL) - return 1; - - JS_SetErrorReporter(cx, couch_error); - JS_ToggleOptions(cx, JSOPTION_XML); - JS_SetOptions(cx, JSOPTION_METHODJIT); -#ifdef JSOPTION_TYPE_INFERENCE - JS_SetOptions(cx, JSOPTION_TYPE_INFERENCE); -#endif - JS_SetContextPrivate(cx, args); - JS_SetRuntimeSecurityCallbacks(rt, &security_callbacks); - - SETUP_REQUEST(cx); - - global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL); - if(global == NULL) - return 1; - - call = JS_EnterCrossCompartmentCall(cx, global); - - JS_SetGlobalObject(cx, global); - - if(!JS_InitStandardClasses(cx, global)) - return 1; - - if(couch_load_funcs(cx, global, global_functions) != JS_TRUE) - return 1; - - for(i = 0 ; args->scripts[i] ; i++) { - // Convert script source to jschars. - scriptsrc = couch_readfile(cx, args->scripts[i]); - if(!scriptsrc) - return 1; - - schars = JS_GetStringCharsAndLength(cx, scriptsrc, &slen); - - // Root it so GC doesn't collect it. - sroot = STRING_TO_JSVAL(scriptsrc); - if(JS_AddValueRoot(cx, &sroot) != JS_TRUE) { - fprintf(stderr, "Internal root error.\n"); - return 1; - } - - // Compile and run - script = JS_CompileUCScript(cx, global, schars, slen, - args->scripts[i], 1); - if(!script) { - fprintf(stderr, "Failed to compile script.\n"); - return 1; - } - - if(JS_ExecuteScript(cx, global, script, &result) != JS_TRUE) { - fprintf(stderr, "Failed to execute script.\n"); - return 1; - } - - // Warning message if we don't remove it. - JS_RemoveValueRoot(cx, &sroot); - - // Give the GC a chance to run. - JS_MaybeGC(cx); - } - - JS_LeaveCrossCompartmentCall(call); - FINISH_REQUEST(cx); - JS_DestroyContext(cx); - JS_DestroyRuntime(rt); - JS_ShutDown(); - - return 0; -} diff --git a/src/couch/priv/couch_js/1.8.5/utf8.c b/src/couch/priv/couch_js/1.8.5/utf8.c deleted file mode 100644 index 4cdb9c21f..000000000 --- a/src/couch/priv/couch_js/1.8.5/utf8.c +++ /dev/null @@ -1,297 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. - -#include <jsapi.h> -#include "config.h" - -static int -enc_char(uint8 *utf8Buffer, uint32 ucs4Char) -{ - int utf8Length = 1; - - if (ucs4Char < 0x80) - { - *utf8Buffer = (uint8)ucs4Char; - } - else - { - int i; - uint32 a = ucs4Char >> 11; - utf8Length = 2; - while(a) - { - a >>= 5; - utf8Length++; - } - i = utf8Length; - while(--i) - { - utf8Buffer[i] = (uint8)((ucs4Char & 0x3F) | 0x80); - ucs4Char >>= 6; - } - *utf8Buffer = (uint8)(0x100 - (1 << (8-utf8Length)) + ucs4Char); - } - - return utf8Length; -} - -static JSBool -enc_charbuf(const jschar* src, size_t srclen, char* dst, size_t* dstlenp) -{ - size_t i; - size_t utf8Len; - size_t dstlen = *dstlenp; - size_t origDstlen = dstlen; - jschar c; - jschar c2; - uint32 v; - uint8 utf8buf[6]; - - if(!dst) - { - dstlen = origDstlen = (size_t) -1; - } - - while(srclen) - { - c = *src++; - srclen--; - - if(c <= 0xD7FF || c >= 0xE000) - { - v = (uint32) c; - } - else if(c >= 0xD800 && c <= 0xDBFF) - { - if(srclen < 1) goto buffer_too_small; - c2 = *src++; - srclen--; - if(c2 >= 0xDC00 && c2 <= 0xDFFF) - { - v = (uint32) (((c - 0xD800) << 10) + (c2 - 0xDC00) + 0x10000); - } - else - { - // Invalid second half of surrogate pair - v = (uint32) 0xFFFD; - // Undo our character advancement - src--; - srclen++; - } - } - else - { - // Invalid first half surrogate pair - v = (uint32) 0xFFFD; - } - - if(v < 0x0080) - { - /* no encoding necessary - performance hack */ - if(!dstlen) goto buffer_too_small; - if(dst) *dst++ = (char) v; - utf8Len = 1; - } - else - { - utf8Len = enc_char(utf8buf, v); - if(utf8Len > dstlen) goto buffer_too_small; - if(dst) - { - for (i = 0; i < utf8Len; i++) - { - *dst++ = (char) utf8buf[i]; - } - } - } - dstlen -= utf8Len; - } - - *dstlenp = (origDstlen - dstlen); - return JS_TRUE; - -buffer_too_small: - *dstlenp = (origDstlen - dstlen); - return JS_FALSE; -} - -char* -enc_string(JSContext* cx, jsval arg, size_t* buflen) -{ - JSString* str = NULL; - const jschar* src = NULL; - char* bytes = NULL; - size_t srclen = 0; - size_t byteslen = 0; - - str = JS_ValueToString(cx, arg); - if(!str) goto error; - -#ifdef HAVE_JS_GET_STRING_CHARS_AND_LENGTH - src = JS_GetStringCharsAndLength(cx, str, &srclen); -#else - src = JS_GetStringChars(str); - srclen = JS_GetStringLength(str); -#endif - - if(!enc_charbuf(src, srclen, NULL, &byteslen)) goto error; - - bytes = JS_malloc(cx, (byteslen) + 1); - bytes[byteslen] = 0; - - if(!enc_charbuf(src, srclen, bytes, &byteslen)) goto error; - - if(buflen) *buflen = byteslen; - goto success; - -error: - if(bytes != NULL) JS_free(cx, bytes); - bytes = NULL; - -success: - return bytes; -} - -static uint32 -dec_char(const uint8 *utf8Buffer, int utf8Length) -{ - uint32 ucs4Char; - uint32 minucs4Char; - - /* from Unicode 3.1, non-shortest form is illegal */ - static const uint32 minucs4Table[] = { - 0x00000080, 0x00000800, 0x0001000, 0x0020000, 0x0400000 - }; - - if (utf8Length == 1) - { - ucs4Char = *utf8Buffer; - } - else - { - ucs4Char = *utf8Buffer++ & ((1<<(7-utf8Length))-1); - minucs4Char = minucs4Table[utf8Length-2]; - while(--utf8Length) - { - ucs4Char = ucs4Char<<6 | (*utf8Buffer++ & 0x3F); - } - if(ucs4Char < minucs4Char || ucs4Char == 0xFFFE || ucs4Char == 0xFFFF) - { - ucs4Char = 0xFFFD; - } - } - - return ucs4Char; -} - -static JSBool -dec_charbuf(const char *src, size_t srclen, jschar *dst, size_t *dstlenp) -{ - uint32 v; - size_t offset = 0; - size_t j; - size_t n; - size_t dstlen = *dstlenp; - size_t origDstlen = dstlen; - - if(!dst) dstlen = origDstlen = (size_t) -1; - - while(srclen) - { - v = (uint8) *src; - n = 1; - - if(v & 0x80) - { - while(v & (0x80 >> n)) - { - n++; - } - - if(n > srclen) goto buffer_too_small; - if(n == 1 || n > 6) goto bad_character; - - for(j = 1; j < n; j++) - { - if((src[j] & 0xC0) != 0x80) goto bad_character; - } - - v = dec_char((const uint8 *) src, n); - if(v >= 0x10000) - { - v -= 0x10000; - - if(v > 0xFFFFF || dstlen < 2) - { - *dstlenp = (origDstlen - dstlen); - return JS_FALSE; - } - - if(dstlen < 2) goto buffer_too_small; - - if(dst) - { - *dst++ = (jschar)((v >> 10) + 0xD800); - v = (jschar)((v & 0x3FF) + 0xDC00); - } - dstlen--; - } - } - - if(!dstlen) goto buffer_too_small; - if(dst) *dst++ = (jschar) v; - - dstlen--; - offset += n; - src += n; - srclen -= n; - } - - *dstlenp = (origDstlen - dstlen); - return JS_TRUE; - -bad_character: - *dstlenp = (origDstlen - dstlen); - return JS_FALSE; - -buffer_too_small: - *dstlenp = (origDstlen - dstlen); - return JS_FALSE; -} - -JSString* -dec_string(JSContext* cx, const char* bytes, size_t byteslen) -{ - JSString* str = NULL; - jschar* chars = NULL; - size_t charslen; - - if(!dec_charbuf(bytes, byteslen, NULL, &charslen)) goto error; - - chars = JS_malloc(cx, (charslen + 1) * sizeof(jschar)); - if(!chars) return NULL; - chars[charslen] = 0; - - if(!dec_charbuf(bytes, byteslen, chars, &charslen)) goto error; - - str = JS_NewUCString(cx, chars, charslen - 1); - if(!str) goto error; - - goto success; - -error: - if(chars != NULL) JS_free(cx, chars); - str = NULL; - -success: - return str; -} diff --git a/src/couch/priv/couch_js/1.8.5/utf8.h b/src/couch/priv/couch_js/1.8.5/utf8.h deleted file mode 100644 index c5cb86c46..000000000 --- a/src/couch/priv/couch_js/1.8.5/utf8.h +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. - -#ifndef COUCH_JS_UTF_8_H -#define COUCH_JS_UTF_8_H - -char* enc_string(JSContext* cx, jsval arg, size_t* buflen); -JSString* dec_string(JSContext* cx, const char* buf, size_t buflen); - -#endif diff --git a/src/couch/priv/couch_js/1.8.5/util.c b/src/couch/priv/couch_js/1.8.5/util.c deleted file mode 100644 index 5cf94b63a..000000000 --- a/src/couch/priv/couch_js/1.8.5/util.c +++ /dev/null @@ -1,296 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. - -#include <stdlib.h> -#include <string.h> - -#include <jsapi.h> - -#include "help.h" -#include "util.h" -#include "utf8.h" - - -size_t -slurp_file(const char* file, char** outbuf_p) -{ - FILE* fp; - char fbuf[16384]; - char *buf = NULL; - char* tmp; - size_t nread = 0; - size_t buflen = 0; - - if(strcmp(file, "-") == 0) { - fp = stdin; - } else { - fp = fopen(file, "r"); - if(fp == NULL) { - fprintf(stderr, "Failed to read file: %s\n", file); - exit(3); - } - } - - while((nread = fread(fbuf, 1, 16384, fp)) > 0) { - if(buf == NULL) { - buf = (char*) malloc(nread + 1); - if(buf == NULL) { - fprintf(stderr, "Out of memory.\n"); - exit(3); - } - memcpy(buf, fbuf, nread); - } else { - tmp = (char*) malloc(buflen + nread + 1); - if(tmp == NULL) { - fprintf(stderr, "Out of memory.\n"); - exit(3); - } - memcpy(tmp, buf, buflen); - memcpy(tmp+buflen, fbuf, nread); - free(buf); - buf = tmp; - } - buflen += nread; - buf[buflen] = '\0'; - } - *outbuf_p = buf; - return buflen + 1; -} - -couch_args* -couch_parse_args(int argc, const char* argv[]) -{ - couch_args* args; - int i = 1; - - args = (couch_args*) malloc(sizeof(couch_args)); - if(args == NULL) - return NULL; - - memset(args, '\0', sizeof(couch_args)); - args->stack_size = 64L * 1024L * 1024L; - - while(i < argc) { - if(strcmp("-h", argv[i]) == 0) { - DISPLAY_USAGE; - exit(0); - } else if(strcmp("-V", argv[i]) == 0) { - DISPLAY_VERSION; - exit(0); - } else if(strcmp("-H", argv[i]) == 0) { - args->use_http = 1; - } else if(strcmp("-T", argv[i]) == 0) { - args->use_test_funs = 1; - } else if(strcmp("-S", argv[i]) == 0) { - args->stack_size = atoi(argv[++i]); - if(args->stack_size <= 0) { - fprintf(stderr, "Invalid stack size.\n"); - exit(2); - } - } else if(strcmp("--eval", argv[i]) == 0) { - args->eval = 1; - } else if(strcmp("--", argv[i]) == 0) { - i++; - break; - } else { - break; - } - i++; - } - - if(i >= argc) { - DISPLAY_USAGE; - exit(3); - } - args->scripts = argv + i; - - return args; -} - - -int -couch_fgets(char* buf, int size, FILE* fp) -{ - int n, i, c; - - if(size <= 0) return -1; - n = size - 1; - - for(i = 0; i < n && (c = getc(fp)) != EOF; i++) { - buf[i] = c; - if(c == '\n') { - i++; - break; - } - } - - buf[i] = '\0'; - return i; -} - - -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; -} - - -JSString* -couch_readfile(JSContext* cx, const char* filename) -{ - JSString *string; - size_t byteslen; - char *bytes; - - if((byteslen = slurp_file(filename, &bytes))) { - string = dec_string(cx, bytes, byteslen); - - free(bytes); - return string; - } - return NULL; -} - - -void -couch_print(JSContext* cx, uintN argc, jsval* argv) -{ - char *bytes = NULL; - FILE *stream = stdout; - - if (argc) { - if (argc > 1 && argv[1] == JSVAL_TRUE) { - stream = stderr; - } - bytes = enc_string(cx, argv[0], NULL); - if(!bytes) return; - fprintf(stream, "%s", bytes); - JS_free(cx, bytes); - } - - fputc('\n', stream); - fflush(stream); -} - - -void -couch_error(JSContext* cx, const char* mesg, JSErrorReport* report) -{ - jsval v, replace; - char* bytes; - JSObject* regexp, *stack; - jsval re_args[2]; - - if(!report || !JSREPORT_IS_WARNING(report->flags)) - { - fprintf(stderr, "%s\n", mesg); - - // Print a stack trace, if available. - if (JSREPORT_IS_EXCEPTION(report->flags) && - JS_GetPendingException(cx, &v)) - { - // Clear the exception before an JS method calls or the result is - // infinite, recursive error report generation. - JS_ClearPendingException(cx); - - // Use JS regexp to indent the stack trace. - // If the regexp can't be created, don't JS_ReportError since it is - // probably not productive to wind up here again. -#ifdef SM185 - if(JS_GetProperty(cx, JSVAL_TO_OBJECT(v), "stack", &v) && - (regexp = JS_NewRegExpObjectNoStatics( - cx, "^(?=.)", 6, JSREG_GLOB | JSREG_MULTILINE))) -#else - if(JS_GetProperty(cx, JSVAL_TO_OBJECT(v), "stack", &v) && - (regexp = JS_NewRegExpObject( - cx, "^(?=.)", 6, JSREG_GLOB | JSREG_MULTILINE))) -#endif - { - // Set up the arguments to ``String.replace()`` - re_args[0] = OBJECT_TO_JSVAL(regexp); - re_args[1] = STRING_TO_JSVAL(JS_InternString(cx, "\t")); - - // Perform the replacement - if(JS_ValueToObject(cx, v, &stack) && - JS_GetProperty(cx, stack, "replace", &replace) && - JS_CallFunctionValue(cx, stack, replace, 2, re_args, &v)) - { - // Print the result - bytes = enc_string(cx, v, NULL); - fprintf(stderr, "Stacktrace:\n%s", bytes); - JS_free(cx, bytes); - } - } - } - } -} - - -JSBool -couch_load_funcs(JSContext* cx, JSObject* obj, JSFunctionSpec* funcs) -{ - JSFunctionSpec* f; - for(f = funcs; f->name != NULL; f++) { - if(!JS_DefineFunction(cx, obj, f->name, f->call, f->nargs, f->flags)) { - fprintf(stderr, "Failed to create function: %s\n", f->name); - return JS_FALSE; - } - } - return JS_TRUE; -} diff --git a/src/couch/priv/couch_js/1.8.5/util.h b/src/couch/priv/couch_js/1.8.5/util.h deleted file mode 100644 index 9dd290a4c..000000000 --- a/src/couch/priv/couch_js/1.8.5/util.h +++ /dev/null @@ -1,35 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. - -#ifndef COUCHJS_UTIL_H -#define COUCHJS_UTIL_H - -#include <jsapi.h> - -typedef struct { - int eval; - int use_http; - int use_test_funs; - int stack_size; - const char** scripts; -} couch_args; - -couch_args* couch_parse_args(int argc, const char* argv[]); -int couch_fgets(char* buf, int size, FILE* fp); -JSString* couch_readline(JSContext* cx, FILE* fp); -JSString* couch_readfile(JSContext* cx, const char* filename); -void couch_print(JSContext* cx, uintN argc, jsval* argv); -void couch_error(JSContext* cx, const char* mesg, JSErrorReport* report); -JSBool couch_load_funcs(JSContext* cx, JSObject* obj, JSFunctionSpec* funcs); - - -#endif // Included util.h diff --git a/src/couch/priv/couch_js/60/help.h b/src/couch/priv/couch_js/60/help.h deleted file mode 100644 index 826babbba..000000000 --- a/src/couch/priv/couch_js/60/help.h +++ /dev/null @@ -1,79 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. - -#ifndef COUCHJS_HELP_H -#define COUCHJS_HELP_H - -#include "config.h" - -static const char VERSION_TEMPLATE[] = - "%s - %s (SpiderMonkey 60)\n" - "\n" - "Licensed under the Apache License, Version 2.0 (the \"License\"); you may " - "not use\n" - "this file except in compliance with the License. You may obtain a copy of" - "the\n" - "License at\n" - "\n" - " http://www.apache.org/licenses/LICENSE-2.0\n" - "\n" - "Unless required by applicable law or agreed to in writing, software " - "distributed\n" - "under the License is distributed on an \"AS IS\" BASIS, WITHOUT " - "WARRANTIES OR\n" - "CONDITIONS OF ANY KIND, either express or implied. See the License " - "for the\n" - "specific language governing permissions and limitations under the " - "License.\n"; - -static const char USAGE_TEMPLATE[] = - "Usage: %s [FILE]\n" - "\n" - "The %s command runs the %s JavaScript interpreter.\n" - "\n" - "The exit status is 0 for success or 1 for failure.\n" - "\n" - "Options:\n" - "\n" - " -h display a short help message and exit\n" - " -V display version information and exit\n" - " -S SIZE specify that the runtime should allow at\n" - " most SIZE bytes of memory to be allocated\n" - " default is 64 MiB\n" - " --eval Enable runtime code evaluation (dangerous!)\n" - "\n" - "Report bugs at <%s>.\n"; - -#define BASENAME COUCHJS_NAME - -#define couch_version(basename) \ - fprintf( \ - stdout, \ - VERSION_TEMPLATE, \ - basename, \ - PACKAGE_STRING) - -#define DISPLAY_VERSION couch_version(BASENAME) - - -#define couch_usage(basename) \ - fprintf( \ - stdout, \ - USAGE_TEMPLATE, \ - basename, \ - basename, \ - PACKAGE_NAME, \ - PACKAGE_BUGREPORT) - -#define DISPLAY_USAGE couch_usage(BASENAME) - -#endif // Included help.h diff --git a/src/couch/priv/couch_js/60/main.cpp b/src/couch/priv/couch_js/60/main.cpp deleted file mode 100644 index 5169b05d7..000000000 --- a/src/couch/priv/couch_js/60/main.cpp +++ /dev/null @@ -1,336 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#ifdef XP_WIN -#define NOMINMAX -#include <windows.h> -#else -#include <unistd.h> -#endif - -#include <jsapi.h> -#include <js/Initialization.h> -#include <js/Conversions.h> -#include <js/Wrapper.h> - -#include "config.h" -#include "util.h" - -static bool enableSharedMemory = true; - -static JSClassOps global_ops = { - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - JS_GlobalObjectTraceHook -}; - -/* The class of the global object. */ -static JSClass global_class = { - "global", - JSCLASS_GLOBAL_FLAGS, - &global_ops -}; - -static void -SetStandardCompartmentOptions(JS::CompartmentOptions& options) -{ - options.creationOptions().setSharedMemoryAndAtomicsEnabled(enableSharedMemory); -} - -static JSObject* -NewSandbox(JSContext* cx, bool lazy) -{ - JS::CompartmentOptions options; - SetStandardCompartmentOptions(options); - JS::RootedObject obj(cx, JS_NewGlobalObject(cx, &global_class, nullptr, - JS::DontFireOnNewGlobalHook, options)); - if (!obj) - return nullptr; - - { - JSAutoCompartment ac(cx, obj); - if (!lazy && !JS_InitStandardClasses(cx, obj)) - return nullptr; - - JS::RootedValue value(cx, JS::BooleanValue(lazy)); - if (!JS_DefineProperty(cx, obj, "lazy", value, JSPROP_PERMANENT | JSPROP_READONLY)) - return nullptr; - - JS_FireOnNewGlobalObject(cx, obj); - } - - if (!JS_WrapObject(cx, &obj)) - return nullptr; - return obj; -} - -static bool -evalcx(JSContext *cx, unsigned int argc, JS::Value* vp) -{ - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - bool ret = false; - - JS::RootedString str(cx, JS::ToString(cx, args[0])); - if (!str) - return false; - - JS::RootedObject sandbox(cx); - if (args.hasDefined(1)) { - sandbox = JS::ToObject(cx, args[1]); - if (!sandbox) - return false; - } - - JSAutoRequest ar(cx); - - if (!sandbox) { - sandbox = NewSandbox(cx, false); - if (!sandbox) - return false; - } - - js::AutoStableStringChars strChars(cx); - if (!strChars.initTwoByte(cx, str)) - return false; - - mozilla::Range<const char16_t> chars = strChars.twoByteRange(); - size_t srclen = chars.length(); - const char16_t* src = chars.begin().get(); - - if(srclen == 0) { - args.rval().setObject(*sandbox); - } else { - mozilla::Maybe<JSAutoCompartment> ac; - unsigned flags; - JSObject* unwrapped = UncheckedUnwrap(sandbox, true, &flags); - if (flags & js::Wrapper::CROSS_COMPARTMENT) { - sandbox = unwrapped; - ac.emplace(cx, sandbox); - } - - JS::CompileOptions opts(cx); - JS::RootedValue rval(cx); - opts.setFileAndLine("<unknown>", 1); - if (!JS::Evaluate(cx, opts, src, srclen, args.rval())) { - return false; - } - } - ret = true; - if (!JS_WrapValue(cx, args.rval())) - return false; - - return ret; -} - - -static bool -gc(JSContext* cx, unsigned int argc, JS::Value* vp) -{ - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - JS_GC(cx); - args.rval().setUndefined(); - return true; -} - - -static bool -print(JSContext* cx, unsigned int argc, JS::Value* vp) -{ - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - - bool use_stderr = false; - if(argc > 1 && args[1].isTrue()) { - use_stderr = true; - } - - if(!args[0].isString()) { - JS_ReportErrorUTF8(cx, "Unable to print non-string value."); - return false; - } - - couch_print(cx, args[0], use_stderr); - - args.rval().setUndefined(); - return true; -} - - -static bool -quit(JSContext* cx, unsigned int argc, JS::Value* vp) -{ - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - - int exit_code = args[0].toInt32();; - exit(exit_code); -} - - -static bool -readline(JSContext* cx, unsigned int argc, JS::Value* vp) -{ - JSString* line; - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - - /* GC Occasionally */ - JS_MaybeGC(cx); - - line = couch_readline(cx, stdin); - if(line == NULL) return false; - - // return with JSString* instead of JSValue in the past - args.rval().setString(line); - return true; -} - - -static bool -seal(JSContext* cx, unsigned int argc, JS::Value* vp) -{ - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - JS::RootedObject target(cx); - target = JS::ToObject(cx, args[0]); - if (!target) { - args.rval().setUndefined(); - return true; - } - bool deep = false; - deep = args[1].toBoolean(); - bool ret = deep ? JS_DeepFreezeObject(cx, target) : JS_FreezeObject(cx, target); - args.rval().setUndefined(); - return ret; -} - - -static JSFunctionSpec global_functions[] = { - JS_FN("evalcx", evalcx, 0, 0), - JS_FN("gc", gc, 0, 0), - JS_FN("print", print, 0, 0), - JS_FN("quit", quit, 0, 0), - JS_FN("readline", readline, 0, 0), - JS_FN("seal", seal, 0, 0), - JS_FS_END -}; - - -static bool -csp_allows(JSContext* cx) -{ - couch_args* args = static_cast<couch_args*>(JS_GetContextPrivate(cx)); - if(args->eval) { - return true; - } else { - return false; - } -} - - -static JSSecurityCallbacks security_callbacks = { - csp_allows, - nullptr -}; - - -int -main(int argc, const char* argv[]) -{ - JSContext* cx = NULL; - char* scriptsrc; - size_t slen; - int i; - - couch_args* args = couch_parse_args(argc, argv); - - JS_Init(); - cx = JS_NewContext(args->stack_size, 8L * 1024L); - if(cx == NULL) - return 1; - - JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_BASELINE_ENABLE, 0); - JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_ION_ENABLE, 0); - - if (!JS::InitSelfHostedCode(cx)) - return 1; - - JS::SetWarningReporter(cx, couch_error); - JS::SetOutOfMemoryCallback(cx, couch_oom, NULL); - JS_SetContextPrivate(cx, args); - JS_SetSecurityCallbacks(cx, &security_callbacks); - - JSAutoRequest ar(cx); - JS::CompartmentOptions options; - JS::RootedObject global(cx, JS_NewGlobalObject(cx, &global_class, nullptr, - JS::FireOnNewGlobalHook, options)); - if (!global) - return 1; - - JSAutoCompartment ac(cx, global); - - if(!JS_InitStandardClasses(cx, global)) - return 1; - - if(couch_load_funcs(cx, global, global_functions) != true) - return 1; - - for(i = 0 ; args->scripts[i] ; i++) { - slen = couch_readfile(args->scripts[i], &scriptsrc); - - // Compile and run - JS::CompileOptions options(cx); - options.setFileAndLine(args->scripts[i], 1); - options.setUTF8(true); - JS::RootedScript script(cx); - - if(!JS_CompileScript(cx, scriptsrc, slen, options, &script)) { - JS::RootedValue exc(cx); - if(!JS_GetPendingException(cx, &exc)) { - fprintf(stderr, "Failed to compile script.\n"); - } else { - JS::RootedObject exc_obj(cx, &exc.toObject()); - JSErrorReport* report = JS_ErrorFromException(cx, exc_obj); - couch_error(cx, report); - } - return 1; - } - - free(scriptsrc); - - JS::RootedValue result(cx); - if(JS_ExecuteScript(cx, script, &result) != true) { - JS::RootedValue exc(cx); - if(!JS_GetPendingException(cx, &exc)) { - fprintf(stderr, "Failed to execute script.\n"); - } else { - JS::RootedObject exc_obj(cx, &exc.toObject()); - JSErrorReport* report = JS_ErrorFromException(cx, exc_obj); - couch_error(cx, report); - } - return 1; - } - - // Give the GC a chance to run. - JS_MaybeGC(cx); - } - - return 0; -} diff --git a/src/couch/priv/couch_js/60/util.cpp b/src/couch/priv/couch_js/60/util.cpp deleted file mode 100644 index 3bc58a921..000000000 --- a/src/couch/priv/couch_js/60/util.cpp +++ /dev/null @@ -1,355 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. - -#include <stdlib.h> -#include <string.h> - -#include <sstream> - -#include <jsapi.h> -#include <js/Initialization.h> -#include <js/CharacterEncoding.h> -#include <js/Conversions.h> -#include <mozilla/Unused.h> - -#include "help.h" -#include "util.h" - -std::string -js_to_string(JSContext* cx, JS::HandleValue val) -{ - JS::AutoSaveExceptionState exc_state(cx); - JS::RootedString sval(cx); - sval = val.toString(); - - JS::UniqueChars chars(JS_EncodeStringToUTF8(cx, sval)); - if(!chars) { - JS_ClearPendingException(cx); - return std::string(); - } - - return chars.get(); -} - -bool -js_to_string(JSContext* cx, JS::HandleValue val, std::string& str) -{ - if(!val.isString()) { - return false; - } - - if(JS_GetStringLength(val.toString()) == 0) { - str = ""; - return true; - } - - std::string conv = js_to_string(cx, val); - if(!conv.size()) { - return false; - } - - str = conv; - return true; -} - -JSString* -string_to_js(JSContext* cx, const std::string& raw) -{ - JS::UTF8Chars utf8(raw.c_str(), raw.size()); - JS::UniqueTwoByteChars utf16; - size_t len; - - utf16.reset(JS::UTF8CharsToNewTwoByteCharsZ(cx, utf8, &len).get()); - if(!utf16) { - return nullptr; - } - - JSString* ret = JS_NewUCString(cx, utf16.get(), len); - - if(ret) { - // JS_NewUCString took ownership on success. We shift - // the resulting pointer into Unused to silence the - // compiler warning. - mozilla::Unused << utf16.release(); - } - - return ret; -} - -size_t -couch_readfile(const char* file, char** outbuf_p) -{ - FILE* fp; - char fbuf[16384]; - char *buf = NULL; - char* tmp; - size_t nread = 0; - size_t buflen = 0; - - if(strcmp(file, "-") == 0) { - fp = stdin; - } else { - fp = fopen(file, "r"); - if(fp == NULL) { - fprintf(stderr, "Failed to read file: %s\n", file); - exit(3); - } - } - - while((nread = fread(fbuf, 1, 16384, fp)) > 0) { - if(buf == NULL) { - buf = new char[nread + 1]; - if(buf == NULL) { - fprintf(stderr, "Out of memory.\n"); - exit(3); - } - memcpy(buf, fbuf, nread); - } else { - tmp = new char[buflen + nread + 1]; - if(tmp == NULL) { - fprintf(stderr, "Out of memory.\n"); - exit(3); - } - memcpy(tmp, buf, buflen); - memcpy(tmp+buflen, fbuf, nread); - delete buf; - buf = tmp; - } - buflen += nread; - buf[buflen] = '\0'; - } - *outbuf_p = buf; - return buflen ; -} - -couch_args* -couch_parse_args(int argc, const char* argv[]) -{ - couch_args* args; - int i = 1; - - args = new couch_args(); - if(args == NULL) - return NULL; - - args->eval = 0; - args->stack_size = 64L * 1024L * 1024L; - args->scripts = nullptr; - - while(i < argc) { - if(strcmp("-h", argv[i]) == 0) { - DISPLAY_USAGE; - exit(0); - } else if(strcmp("-V", argv[i]) == 0) { - DISPLAY_VERSION; - exit(0); - } else if(strcmp("-S", argv[i]) == 0) { - args->stack_size = atoi(argv[++i]); - if(args->stack_size <= 0) { - fprintf(stderr, "Invalid stack size.\n"); - exit(2); - } - } else if(strcmp("--eval", argv[i]) == 0) { - args->eval = 1; - } else if(strcmp("--", argv[i]) == 0) { - i++; - break; - } else { - break; - } - i++; - } - - if(i >= argc) { - DISPLAY_USAGE; - exit(3); - } - args->scripts = argv + i; - - return args; -} - - -int -couch_fgets(char* buf, int size, FILE* fp) -{ - int n, i, c; - - if(size <= 0) return -1; - n = size - 1; - - for(i = 0; i < n && (c = getc(fp)) != EOF; i++) { - buf[i] = c; - if(c == '\n') { - i++; - break; - } - } - - buf[i] = '\0'; - return i; -} - - -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 oldbyteslen = 256; - size_t readlen = 0; - - bytes = static_cast<char*>(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. - oldbyteslen = byteslen; - byteslen *= 2; - tmp = static_cast<char*>(JS_realloc(cx, bytes, oldbyteslen, byteslen)); - if(!tmp) { - JS_free(cx, bytes); - return NULL; - } - - bytes = tmp; - } - - // Treat empty strings specially - if(used == 0) { - JS_free(cx, bytes); - return JS_NewStringCopyZ(cx, nullptr); - } - - // Shrink the buffer to the actual data size - tmp = static_cast<char*>(JS_realloc(cx, bytes, byteslen, used)); - if(!tmp) { - JS_free(cx, bytes); - return NULL; - } - bytes = tmp; - byteslen = used; - - str = string_to_js(cx, std::string(tmp)); - JS_free(cx, bytes); - return str; -} - - -void -couch_print(JSContext* cx, JS::HandleValue obj, bool use_stderr) -{ - FILE* stream = stdout; - - if(use_stderr) { - stream = stderr; - } - - std::string val = js_to_string(cx, obj); - fprintf(stream, "%s\n", val.c_str()); - fflush(stream); -} - - -void -couch_error(JSContext* cx, JSErrorReport* report) -{ - if(!report) { - return; - } - - if(JSREPORT_IS_WARNING(report->flags)) { - return; - } - - std::ostringstream msg; - msg << "error: " << report->message().c_str(); - - mozilla::Maybe<JSAutoCompartment> ac; - JS::RootedValue exc(cx); - JS::RootedObject exc_obj(cx); - JS::RootedObject stack_obj(cx); - JS::RootedString stack_str(cx); - JS::RootedValue stack_val(cx); - - if(!JS_GetPendingException(cx, &exc)) { - goto done; - } - - // Clear the exception before an JS method calls or the result is - // infinite, recursive error report generation. - JS_ClearPendingException(cx); - - exc_obj.set(exc.toObjectOrNull()); - stack_obj.set(JS::ExceptionStackOrNull(exc_obj)); - - if(!stack_obj) { - // Compilation errors don't have a stack - - msg << " at "; - - if(report->filename) { - msg << report->filename; - } else { - msg << "<unknown>"; - } - - if(report->lineno) { - msg << ':' << report->lineno << ':' << report->column; - } - - goto done; - } - - if(!JS::BuildStackString(cx, stack_obj, &stack_str, 2)) { - goto done; - } - - stack_val.set(JS::StringValue(stack_str)); - msg << std::endl << std::endl << js_to_string(cx, stack_val).c_str(); - -done: - msg << std::endl; - fprintf(stderr, "%s", msg.str().c_str()); -} - - -void -couch_oom(JSContext* cx, void* data) -{ - fprintf(stderr, "out of memory\n"); - exit(1); -} - - -bool -couch_load_funcs(JSContext* cx, JS::HandleObject obj, JSFunctionSpec* funcs) -{ - JSFunctionSpec* f; - for(f = funcs; f->name != NULL; f++) { - if(!JS_DefineFunction(cx, obj, f->name, f->call.op, f->nargs, f->flags)) { - fprintf(stderr, "Failed to create function: %s\n", f->name); - return false; - } - } - return true; -} diff --git a/src/couch/priv/couch_js/60/util.h b/src/couch/priv/couch_js/60/util.h deleted file mode 100644 index 35882a614..000000000 --- a/src/couch/priv/couch_js/60/util.h +++ /dev/null @@ -1,38 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. - -#ifndef COUCHJS_UTIL_H -#define COUCHJS_UTIL_H - -#include <jsapi.h> - -typedef struct { - int eval; - int stack_size; - const char** scripts; -} couch_args; - -std::string js_to_string(JSContext* cx, JS::HandleValue val); -bool js_to_string(JSContext* cx, JS::HandleValue val, std::string& str); -JSString* string_to_js(JSContext* cx, const std::string& s); - -couch_args* couch_parse_args(int argc, const char* argv[]); -int couch_fgets(char* buf, int size, FILE* fp); -JSString* couch_readline(JSContext* cx, FILE* fp); -size_t couch_readfile(const char* file, char** outbuf_p); -void couch_print(JSContext* cx, JS::HandleValue str, bool use_stderr); -void couch_error(JSContext* cx, JSErrorReport* report); -void couch_oom(JSContext* cx, void* data); -bool couch_load_funcs(JSContext* cx, JS::HandleObject obj, JSFunctionSpec* funcs); - - -#endif // Included util.h diff --git a/src/couch/priv/couch_js/68/help.h b/src/couch/priv/couch_js/68/help.h deleted file mode 100644 index 7c7550cc2..000000000 --- a/src/couch/priv/couch_js/68/help.h +++ /dev/null @@ -1,79 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. - -#ifndef COUCHJS_HELP_H -#define COUCHJS_HELP_H - -#include "config.h" - -static const char VERSION_TEMPLATE[] = - "%s - %s (SpiderMonkey 68)\n" - "\n" - "Licensed under the Apache License, Version 2.0 (the \"License\"); you may " - "not use\n" - "this file except in compliance with the License. You may obtain a copy of" - "the\n" - "License at\n" - "\n" - " http://www.apache.org/licenses/LICENSE-2.0\n" - "\n" - "Unless required by applicable law or agreed to in writing, software " - "distributed\n" - "under the License is distributed on an \"AS IS\" BASIS, WITHOUT " - "WARRANTIES OR\n" - "CONDITIONS OF ANY KIND, either express or implied. See the License " - "for the\n" - "specific language governing permissions and limitations under the " - "License.\n"; - -static const char USAGE_TEMPLATE[] = - "Usage: %s [FILE]\n" - "\n" - "The %s command runs the %s JavaScript interpreter.\n" - "\n" - "The exit status is 0 for success or 1 for failure.\n" - "\n" - "Options:\n" - "\n" - " -h display a short help message and exit\n" - " -V display version information and exit\n" - " -S SIZE specify that the runtime should allow at\n" - " most SIZE bytes of memory to be allocated\n" - " default is 64 MiB\n" - " --eval Enable runtime code evaluation (dangerous!)\n" - "\n" - "Report bugs at <%s>.\n"; - -#define BASENAME COUCHJS_NAME - -#define couch_version(basename) \ - fprintf( \ - stdout, \ - VERSION_TEMPLATE, \ - basename, \ - PACKAGE_STRING) - -#define DISPLAY_VERSION couch_version(BASENAME) - - -#define couch_usage(basename) \ - fprintf( \ - stdout, \ - USAGE_TEMPLATE, \ - basename, \ - basename, \ - PACKAGE_NAME, \ - PACKAGE_BUGREPORT) - -#define DISPLAY_USAGE couch_usage(BASENAME) - -#endif // Included help.h diff --git a/src/couch/priv/couch_js/68/main.cpp b/src/couch/priv/couch_js/68/main.cpp deleted file mode 100644 index bb62d16ca..000000000 --- a/src/couch/priv/couch_js/68/main.cpp +++ /dev/null @@ -1,337 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#ifdef XP_WIN -#define NOMINMAX -#include <windows.h> -#else -#include <unistd.h> -#endif - -#include <jsapi.h> -#include <js/CompilationAndEvaluation.h> -#include <js/Conversions.h> -#include <js/Initialization.h> -#include <js/SourceText.h> -#include <js/Warnings.h> -#include <js/Wrapper.h> - -#include "config.h" -#include "util.h" - -static bool enableSharedMemory = true; - -static JSClassOps global_ops = { - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - JS_GlobalObjectTraceHook -}; - -/* The class of the global object. */ -static JSClass global_class = { - "global", - JSCLASS_GLOBAL_FLAGS, - &global_ops -}; - -static JSObject* -NewSandbox(JSContext* cx, bool lazy) -{ - JS::RealmOptions options; - options.creationOptions().setSharedMemoryAndAtomicsEnabled(enableSharedMemory); - options.creationOptions().setNewCompartmentAndZone(); - JS::RootedObject obj(cx, JS_NewGlobalObject(cx, &global_class, nullptr, - JS::DontFireOnNewGlobalHook, options)); - if (!obj) - return nullptr; - - { - JSAutoRealm ac(cx, obj); - if (!lazy && !JS::InitRealmStandardClasses(cx)) - return nullptr; - - JS::RootedValue value(cx, JS::BooleanValue(lazy)); - if (!JS_DefineProperty(cx, obj, "lazy", value, JSPROP_PERMANENT | JSPROP_READONLY)) - return nullptr; - - JS_FireOnNewGlobalObject(cx, obj); - } - - if (!JS_WrapObject(cx, &obj)) - return nullptr; - return obj; -} - -static bool -evalcx(JSContext *cx, unsigned int argc, JS::Value* vp) -{ - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - bool ret = false; - - JS::RootedString str(cx, args[0].toString()); - if (!str) - return false; - - JS::RootedObject sandbox(cx); - if (args.hasDefined(1)) { - sandbox = JS::ToObject(cx, args[1]); - if (!sandbox) - return false; - } - - if (!sandbox) { - sandbox = NewSandbox(cx, false); - if (!sandbox) - return false; - } - - JS::AutoStableStringChars strChars(cx); - if (!strChars.initTwoByte(cx, str)) - return false; - - mozilla::Range<const char16_t> chars = strChars.twoByteRange(); - JS::SourceText<char16_t> srcBuf; - if (!srcBuf.init(cx, chars.begin().get(), chars.length(), - JS::SourceOwnership::Borrowed)) { - return false; - } - - if(srcBuf.length() == 0) { - args.rval().setObject(*sandbox); - } else { - mozilla::Maybe<JSAutoRealm> ar; - unsigned flags; - JSObject* unwrapped = UncheckedUnwrap(sandbox, true, &flags); - if (flags & js::Wrapper::CROSS_COMPARTMENT) { - sandbox = unwrapped; - ar.emplace(cx, sandbox); - } - - JS::CompileOptions opts(cx); - JS::RootedValue rval(cx); - opts.setFileAndLine("<unknown>", 1); - - if (!JS::Evaluate(cx, opts, srcBuf, args.rval())) { - return false; - } - } - ret = true; - if (!JS_WrapValue(cx, args.rval())) - return false; - - return ret; -} - - -static bool -gc(JSContext* cx, unsigned int argc, JS::Value* vp) -{ - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - JS_GC(cx); - args.rval().setUndefined(); - return true; -} - - -static bool -print(JSContext* cx, unsigned int argc, JS::Value* vp) -{ - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - - bool use_stderr = false; - if(argc > 1 && args[1].isTrue()) { - use_stderr = true; - } - - if(!args[0].isString()) { - JS_ReportErrorUTF8(cx, "Unable to print non-string value."); - return false; - } - - couch_print(cx, args[0], use_stderr); - - args.rval().setUndefined(); - return true; -} - - -static bool -quit(JSContext* cx, unsigned int argc, JS::Value* vp) -{ - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - - int exit_code = args[0].toInt32();; - exit(exit_code); -} - - -static bool -readline(JSContext* cx, unsigned int argc, JS::Value* vp) -{ - JSString* line; - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - - /* GC Occasionally */ - JS_MaybeGC(cx); - - line = couch_readline(cx, stdin); - if(line == NULL) return false; - - // return with JSString* instead of JSValue in the past - args.rval().setString(line); - return true; -} - - -static bool -seal(JSContext* cx, unsigned int argc, JS::Value* vp) -{ - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - JS::RootedObject target(cx); - target = JS::ToObject(cx, args[0]); - if (!target) { - args.rval().setUndefined(); - return true; - } - bool deep = false; - deep = args[1].toBoolean(); - bool ret = deep ? JS_DeepFreezeObject(cx, target) : JS_FreezeObject(cx, target); - args.rval().setUndefined(); - return ret; -} - - -static JSFunctionSpec global_functions[] = { - JS_FN("evalcx", evalcx, 0, 0), - JS_FN("gc", gc, 0, 0), - JS_FN("print", print, 0, 0), - JS_FN("quit", quit, 0, 0), - JS_FN("readline", readline, 0, 0), - JS_FN("seal", seal, 0, 0), - JS_FS_END -}; - - -static bool -csp_allows(JSContext* cx, JS::HandleValue code) -{ - couch_args* args = static_cast<couch_args*>(JS_GetContextPrivate(cx)); - if(args->eval) { - return true; - } else { - return false; - } -} - - -static JSSecurityCallbacks security_callbacks = { - csp_allows, - nullptr -}; - - -int -main(int argc, const char* argv[]) -{ - JSContext* cx = NULL; - int i; - - couch_args* args = couch_parse_args(argc, argv); - - JS_Init(); - cx = JS_NewContext(args->stack_size, 8L * 1024L); - if(cx == NULL) - return 1; - - JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_BASELINE_ENABLE, 0); - JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_ION_ENABLE, 0); - - if (!JS::InitSelfHostedCode(cx)) - return 1; - - JS::SetWarningReporter(cx, couch_error); - JS::SetOutOfMemoryCallback(cx, couch_oom, NULL); - JS_SetContextPrivate(cx, args); - JS_SetSecurityCallbacks(cx, &security_callbacks); - - JS::RealmOptions options; - JS::RootedObject global(cx, JS_NewGlobalObject(cx, &global_class, nullptr, - JS::FireOnNewGlobalHook, options)); - if (!global) - return 1; - - JSAutoRealm ar(cx, global); - - if(!JS::InitRealmStandardClasses(cx)) - return 1; - - if(couch_load_funcs(cx, global, global_functions) != true) - return 1; - - for(i = 0 ; args->scripts[i] ; i++) { - const char* filename = args->scripts[i]; - - // Compile and run - JS::CompileOptions options(cx); - options.setFileAndLine(filename, 1); - JS::RootedScript script(cx); - FILE* fp; - - fp = fopen(args->scripts[i], "r"); - if(fp == NULL) { - fprintf(stderr, "Failed to read file: %s\n", filename); - return 3; - } - script = JS::CompileUtf8File(cx, options, fp); - fclose(fp); - if (!script) { - JS::RootedValue exc(cx); - if(!JS_GetPendingException(cx, &exc)) { - fprintf(stderr, "Failed to compile file: %s\n", filename); - } else { - JS::RootedObject exc_obj(cx, &exc.toObject()); - JSErrorReport* report = JS_ErrorFromException(cx, exc_obj); - couch_error(cx, report); - } - return 1; - } - - JS::RootedValue result(cx); - if(JS_ExecuteScript(cx, script, &result) != true) { - JS::RootedValue exc(cx); - if(!JS_GetPendingException(cx, &exc)) { - fprintf(stderr, "Failed to execute script.\n"); - } else { - JS::RootedObject exc_obj(cx, &exc.toObject()); - JSErrorReport* report = JS_ErrorFromException(cx, exc_obj); - couch_error(cx, report); - } - } - - // Give the GC a chance to run. - JS_MaybeGC(cx); - } - - return 0; -} diff --git a/src/couch/priv/couch_js/68/util.cpp b/src/couch/priv/couch_js/68/util.cpp deleted file mode 100644 index 6e6105df5..000000000 --- a/src/couch/priv/couch_js/68/util.cpp +++ /dev/null @@ -1,348 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. - -#include <stdlib.h> -#include <string.h> - -#include <sstream> - -#include <jsapi.h> -#include <jsfriendapi.h> -#include <js/CharacterEncoding.h> -#include <js/Conversions.h> -#include <js/Initialization.h> -#include <js/MemoryFunctions.h> -#include <js/RegExp.h> - -#include "help.h" -#include "util.h" - -std::string -js_to_string(JSContext* cx, JS::HandleValue val) -{ - JS::AutoSaveExceptionState exc_state(cx); - JS::RootedString sval(cx); - sval = val.toString(); - - JS::UniqueChars chars(JS_EncodeStringToUTF8(cx, sval)); - if(!chars) { - JS_ClearPendingException(cx); - return std::string(); - } - - return chars.get(); -} - -bool -js_to_string(JSContext* cx, JS::HandleValue val, std::string& str) -{ - if(!val.isString()) { - return false; - } - - if(JS_GetStringLength(val.toString()) == 0) { - str = ""; - return true; - } - - std::string conv = js_to_string(cx, val); - if(!conv.size()) { - return false; - } - - str = conv; - return true; -} - -JSString* -string_to_js(JSContext* cx, const std::string& raw) -{ - JS::UTF8Chars utf8(raw.c_str(), raw.size()); - JS::UniqueTwoByteChars utf16; - size_t len; - - utf16.reset(JS::UTF8CharsToNewTwoByteCharsZ(cx, utf8, &len, js::MallocArena).get()); - if(!utf16) { - return nullptr; - } - - return JS_NewUCString(cx, std::move(utf16), len); -} - -size_t -couch_readfile(const char* file, char** outbuf_p) -{ - FILE* fp; - char fbuf[16384]; - char *buf = NULL; - char* tmp; - size_t nread = 0; - size_t buflen = 0; - - if(strcmp(file, "-") == 0) { - fp = stdin; - } else { - fp = fopen(file, "r"); - if(fp == NULL) { - fprintf(stderr, "Failed to read file: %s\n", file); - exit(3); - } - } - - while((nread = fread(fbuf, 1, 16384, fp)) > 0) { - if(buf == NULL) { - buf = new char[nread + 1]; - if(buf == NULL) { - fprintf(stderr, "Out of memory.\n"); - exit(3); - } - memcpy(buf, fbuf, nread); - } else { - tmp = new char[buflen + nread + 1]; - if(tmp == NULL) { - fprintf(stderr, "Out of memory.\n"); - exit(3); - } - memcpy(tmp, buf, buflen); - memcpy(tmp+buflen, fbuf, nread); - delete buf; - buf = tmp; - } - buflen += nread; - buf[buflen] = '\0'; - } - *outbuf_p = buf; - return buflen ; -} - -couch_args* -couch_parse_args(int argc, const char* argv[]) -{ - couch_args* args; - int i = 1; - - args = new couch_args(); - if(args == NULL) - return NULL; - - args->eval = 0; - args->stack_size = 64L * 1024L * 1024L; - args->scripts = nullptr; - - while(i < argc) { - if(strcmp("-h", argv[i]) == 0) { - DISPLAY_USAGE; - exit(0); - } else if(strcmp("-V", argv[i]) == 0) { - DISPLAY_VERSION; - exit(0); - } else if(strcmp("-S", argv[i]) == 0) { - args->stack_size = atoi(argv[++i]); - if(args->stack_size <= 0) { - fprintf(stderr, "Invalid stack size.\n"); - exit(2); - } - } else if(strcmp("--eval", argv[i]) == 0) { - args->eval = 1; - } else if(strcmp("--", argv[i]) == 0) { - i++; - break; - } else { - break; - } - i++; - } - - if(i >= argc) { - DISPLAY_USAGE; - exit(3); - } - args->scripts = argv + i; - - return args; -} - - -int -couch_fgets(char* buf, int size, FILE* fp) -{ - int n, i, c; - - if(size <= 0) return -1; - n = size - 1; - - for(i = 0; i < n && (c = getc(fp)) != EOF; i++) { - buf[i] = c; - if(c == '\n') { - i++; - break; - } - } - - buf[i] = '\0'; - return i; -} - - -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 oldbyteslen = 256; - size_t readlen = 0; - - bytes = static_cast<char*>(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. - oldbyteslen = byteslen; - byteslen *= 2; - tmp = static_cast<char*>(JS_realloc(cx, bytes, oldbyteslen, byteslen)); - if(!tmp) { - JS_free(cx, bytes); - return NULL; - } - - bytes = tmp; - } - - // Treat empty strings specially - if(used == 0) { - JS_free(cx, bytes); - return JS_NewStringCopyZ(cx, nullptr); - } - - // Shrink the buffer to the actual data size - tmp = static_cast<char*>(JS_realloc(cx, bytes, byteslen, used)); - if(!tmp) { - JS_free(cx, bytes); - return NULL; - } - bytes = tmp; - byteslen = used; - - str = string_to_js(cx, std::string(tmp)); - JS_free(cx, bytes); - return str; -} - - -void -couch_print(JSContext* cx, JS::HandleValue obj, bool use_stderr) -{ - FILE *stream = stdout; - - if (use_stderr) { - stream = stderr; - } - std::string val = js_to_string(cx, obj); - fprintf(stream, "%s\n", val.c_str()); - fflush(stream); -} - - -void -couch_error(JSContext* cx, JSErrorReport* report) -{ - if(!report) { - return; - } - - if(JSREPORT_IS_WARNING(report->flags)) { - return; - } - - std::ostringstream msg; - msg << "error: " << report->message().c_str(); - - mozilla::Maybe<JSAutoRealm> ar; - JS::RootedValue exc(cx); - JS::RootedObject exc_obj(cx); - JS::RootedObject stack_obj(cx); - JS::RootedString stack_str(cx); - JS::RootedValue stack_val(cx); - JSPrincipals* principals = GetRealmPrincipals(js::GetContextRealm(cx)); - - if(!JS_GetPendingException(cx, &exc)) { - goto done; - } - - // Clear the exception before an JS method calls or the result is - // infinite, recursive error report generation. - JS_ClearPendingException(cx); - - exc_obj.set(exc.toObjectOrNull()); - stack_obj.set(JS::ExceptionStackOrNull(exc_obj)); - - if(!stack_obj) { - // Compilation errors don't have a stack - - msg << " at "; - - if(report->filename) { - msg << report->filename; - } else { - msg << "<unknown>"; - } - - if(report->lineno) { - msg << ':' << report->lineno << ':' << report->column; - } - - goto done; - } - - if(!JS::BuildStackString(cx, principals, stack_obj, &stack_str, 2)) { - goto done; - } - - stack_val.set(JS::StringValue(stack_str)); - msg << std::endl << std::endl << js_to_string(cx, stack_val).c_str(); - -done: - msg << std::endl; - fprintf(stderr, "%s", msg.str().c_str()); -} - - -void -couch_oom(JSContext* cx, void* data) -{ - fprintf(stderr, "out of memory\n"); - exit(1); -} - - -bool -couch_load_funcs(JSContext* cx, JS::HandleObject obj, JSFunctionSpec* funcs) -{ - JSFunctionSpec* f; - for(f = funcs; f->name; f++) { - if(!JS_DefineFunction(cx, obj, f->name.string(), f->call.op, f->nargs, f->flags)) { - fprintf(stderr, "Failed to create function: %s\n", f->name.string()); - return false; - } - } - return true; -} diff --git a/src/couch/priv/couch_js/68/util.h b/src/couch/priv/couch_js/68/util.h deleted file mode 100644 index bd7843eb9..000000000 --- a/src/couch/priv/couch_js/68/util.h +++ /dev/null @@ -1,41 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. - -#ifndef COUCHJS_UTIL_H -#define COUCHJS_UTIL_H - -#include <jsapi.h> - -typedef struct { - int eval; - int use_http; - int use_test_funs; - int stack_size; - const char** scripts; - const char* uri_file; - JSString* uri; -} couch_args; - -std::string js_to_string(JSContext* cx, JS::HandleValue val); -bool js_to_string(JSContext* cx, JS::HandleValue val, std::string& str); -JSString* string_to_js(JSContext* cx, const std::string& s); - -couch_args* couch_parse_args(int argc, const char* argv[]); -int couch_fgets(char* buf, int size, FILE* fp); -JSString* couch_readline(JSContext* cx, FILE* fp); -size_t couch_readfile(const char* file, char** outbuf_p); -void couch_print(JSContext* cx, JS::HandleValue str, bool use_stderr); -void couch_error(JSContext* cx, JSErrorReport* report); -void couch_oom(JSContext* cx, void* data); -bool couch_load_funcs(JSContext* cx, JS::HandleObject obj, JSFunctionSpec* funcs); - -#endif // Included util.h diff --git a/src/couch/priv/couch_js/86/help.h b/src/couch/priv/couch_js/86/help.h deleted file mode 100644 index 6a23172af..000000000 --- a/src/couch/priv/couch_js/86/help.h +++ /dev/null @@ -1,79 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. - -#ifndef COUCHJS_HELP_H -#define COUCHJS_HELP_H - -#include "config.h" - -static const char VERSION_TEMPLATE[] = - "%s - %s (SpiderMonkey 86)\n" - "\n" - "Licensed under the Apache License, Version 2.0 (the \"License\"); you may " - "not use\n" - "this file except in compliance with the License. You may obtain a copy of" - "the\n" - "License at\n" - "\n" - " http://www.apache.org/licenses/LICENSE-2.0\n" - "\n" - "Unless required by applicable law or agreed to in writing, software " - "distributed\n" - "under the License is distributed on an \"AS IS\" BASIS, WITHOUT " - "WARRANTIES OR\n" - "CONDITIONS OF ANY KIND, either express or implied. See the License " - "for the\n" - "specific language governing permissions and limitations under the " - "License.\n"; - -static const char USAGE_TEMPLATE[] = - "Usage: %s [FILE]\n" - "\n" - "The %s command runs the %s JavaScript interpreter.\n" - "\n" - "The exit status is 0 for success or 1 for failure.\n" - "\n" - "Options:\n" - "\n" - " -h display a short help message and exit\n" - " -V display version information and exit\n" - " -S SIZE specify that the runtime should allow at\n" - " most SIZE bytes of memory to be allocated\n" - " default is 64 MiB\n" - " --eval Enable runtime code evaluation (dangerous!)\n" - "\n" - "Report bugs at <%s>.\n"; - -#define BASENAME COUCHJS_NAME - -#define couch_version(basename) \ - fprintf( \ - stdout, \ - VERSION_TEMPLATE, \ - basename, \ - PACKAGE_STRING) - -#define DISPLAY_VERSION couch_version(BASENAME) - - -#define couch_usage(basename) \ - fprintf( \ - stdout, \ - USAGE_TEMPLATE, \ - basename, \ - basename, \ - PACKAGE_NAME, \ - PACKAGE_BUGREPORT) - -#define DISPLAY_USAGE couch_usage(BASENAME) - -#endif // Included help.h diff --git a/src/couch/priv/couch_js/86/main.cpp b/src/couch/priv/couch_js/86/main.cpp deleted file mode 100644 index 3cb4b82c4..000000000 --- a/src/couch/priv/couch_js/86/main.cpp +++ /dev/null @@ -1,344 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#ifdef XP_WIN -#define NOMINMAX -#include <windows.h> -#else -#include <unistd.h> -#endif - -#include <jsapi.h> -#include <js/CompilationAndEvaluation.h> -#include <js/Conversions.h> -#include <js/Initialization.h> -#include <js/SourceText.h> -#include <js/StableStringChars.h> -#include <js/Warnings.h> -#include <js/Wrapper.h> - -#include "config.h" -#include "util.h" - -static bool enableSharedMemory = true; -static bool enableToSource = true; - -static JSClassOps global_ops = { - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - JS_GlobalObjectTraceHook -}; - -/* The class of the global object. */ -static JSClass global_class = { - "global", - JSCLASS_GLOBAL_FLAGS, - &global_ops -}; - -static JSObject* -NewSandbox(JSContext* cx, bool lazy) -{ - JS::RealmOptions options; - options.creationOptions().setSharedMemoryAndAtomicsEnabled(enableSharedMemory); - options.creationOptions().setNewCompartmentAndZone(); - // we need this in the query server error handling - options.creationOptions().setToSourceEnabled(enableToSource); - JS::RootedObject obj(cx, JS_NewGlobalObject(cx, &global_class, nullptr, - JS::DontFireOnNewGlobalHook, options)); - if (!obj) - return nullptr; - - { - JSAutoRealm ac(cx, obj); - if (!lazy && !JS::InitRealmStandardClasses(cx)) - return nullptr; - - JS::RootedValue value(cx, JS::BooleanValue(lazy)); - if (!JS_DefineProperty(cx, obj, "lazy", value, JSPROP_PERMANENT | JSPROP_READONLY)) - return nullptr; - - JS_FireOnNewGlobalObject(cx, obj); - } - - if (!JS_WrapObject(cx, &obj)) - return nullptr; - return obj; -} - -static bool -evalcx(JSContext *cx, unsigned int argc, JS::Value* vp) -{ - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - bool ret = false; - - JS::RootedString str(cx, args[0].toString()); - if (!str) - return false; - - JS::RootedObject sandbox(cx); - if (args.hasDefined(1)) { - sandbox = JS::ToObject(cx, args[1]); - if (!sandbox) - return false; - } - - if (!sandbox) { - sandbox = NewSandbox(cx, false); - if (!sandbox) - return false; - } - - JS::AutoStableStringChars strChars(cx); - if (!strChars.initTwoByte(cx, str)) - return false; - - mozilla::Range<const char16_t> chars = strChars.twoByteRange(); - JS::SourceText<char16_t> srcBuf; - if (!srcBuf.init(cx, chars.begin().get(), chars.length(), - JS::SourceOwnership::Borrowed)) { - return false; - } - - if(srcBuf.length() == 0) { - args.rval().setObject(*sandbox); - } else { - mozilla::Maybe<JSAutoRealm> ar; - unsigned flags; - JSObject* unwrapped = UncheckedUnwrap(sandbox, true, &flags); - if (flags & js::Wrapper::CROSS_COMPARTMENT) { - sandbox = unwrapped; - ar.emplace(cx, sandbox); - } - - JS::CompileOptions opts(cx); - JS::RootedValue rval(cx); - opts.setFileAndLine("<unknown>", 1); - - if (!JS::Evaluate(cx, opts, srcBuf, args.rval())) { - return false; - } - } - ret = true; - if (!JS_WrapValue(cx, args.rval())) - return false; - - return ret; -} - - -static bool -gc(JSContext* cx, unsigned int argc, JS::Value* vp) -{ - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - JS_GC(cx); - args.rval().setUndefined(); - return true; -} - - -static bool -print(JSContext* cx, unsigned int argc, JS::Value* vp) -{ - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - - bool use_stderr = false; - if(argc > 1 && args[1].isTrue()) { - use_stderr = true; - } - - if(!args[0].isString()) { - JS_ReportErrorUTF8(cx, "Unable to print non-string value."); - return false; - } - - couch_print(cx, args[0], use_stderr); - - args.rval().setUndefined(); - return true; -} - - -static bool -quit(JSContext* cx, unsigned int argc, JS::Value* vp) -{ - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - - int exit_code = args[0].toInt32();; - JS_DestroyContext(cx); - JS_ShutDown(); - exit(exit_code); -} - - -static bool -readline(JSContext* cx, unsigned int argc, JS::Value* vp) -{ - JSString* line; - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - - /* GC Occasionally */ - JS_MaybeGC(cx); - - line = couch_readline(cx, stdin); - if(line == NULL) return false; - - // return with JSString* instead of JSValue in the past - args.rval().setString(line); - return true; -} - - -static bool -seal(JSContext* cx, unsigned int argc, JS::Value* vp) -{ - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - JS::RootedObject target(cx); - target = JS::ToObject(cx, args[0]); - if (!target) { - args.rval().setUndefined(); - return true; - } - bool deep = false; - deep = args[1].toBoolean(); - bool ret = deep ? JS_DeepFreezeObject(cx, target) : JS_FreezeObject(cx, target); - args.rval().setUndefined(); - return ret; -} - - -static JSFunctionSpec global_functions[] = { - JS_FN("evalcx", evalcx, 0, 0), - JS_FN("gc", gc, 0, 0), - JS_FN("print", print, 0, 0), - JS_FN("quit", quit, 0, 0), - JS_FN("readline", readline, 0, 0), - JS_FN("seal", seal, 0, 0), - JS_FS_END -}; - - -static bool -csp_allows(JSContext* cx, JS::HandleString code) -{ - couch_args* args = static_cast<couch_args*>(JS_GetContextPrivate(cx)); - if(args->eval) { - return true; - } else { - return false; - } -} - - -static JSSecurityCallbacks security_callbacks = { - csp_allows, - nullptr -}; - -int runWithContext(JSContext* cx, couch_args* args) { - JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_BASELINE_ENABLE, 0); - JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_ION_ENABLE, 0); - - if (!JS::InitSelfHostedCode(cx)) - return 1; - - JS::SetWarningReporter(cx, couch_error); - JS::SetOutOfMemoryCallback(cx, couch_oom, NULL); - JS_SetContextPrivate(cx, args); - JS_SetSecurityCallbacks(cx, &security_callbacks); - - JS::RealmOptions options; - // we need this in the query server error handling - options.creationOptions().setToSourceEnabled(enableToSource); - JS::RootedObject global(cx, JS_NewGlobalObject(cx, &global_class, nullptr, - JS::FireOnNewGlobalHook, options)); - if (!global) - return 1; - - JSAutoRealm ar(cx, global); - - if(!JS::InitRealmStandardClasses(cx)) - return 1; - - if(couch_load_funcs(cx, global, global_functions) != true) - return 1; - - for(int i = 0 ; args->scripts[i] ; i++) { - const char* filename = args->scripts[i]; - - // Compile and run - JS::CompileOptions options(cx); - JS::RootedScript script(cx); - - script = JS::CompileUtf8Path(cx, options, filename); - if (!script) { - JS::RootedValue exc(cx); - if(!JS_GetPendingException(cx, &exc)) { - fprintf(stderr, "Failed to compile file: %s\n", filename); - } else { - JS::RootedObject exc_obj(cx, &exc.toObject()); - JSErrorReport* report = JS_ErrorFromException(cx, exc_obj); - couch_error(cx, report); - } - return 1; - } - - JS::RootedValue result(cx); - if(JS_ExecuteScript(cx, script, &result) != true) { - JS::RootedValue exc(cx); - if(!JS_GetPendingException(cx, &exc)) { - fprintf(stderr, "Failed to execute script.\n"); - } else { - JS::RootedObject exc_obj(cx, &exc.toObject()); - JSErrorReport* report = JS_ErrorFromException(cx, exc_obj); - couch_error(cx, report); - } - } - - // Give the GC a chance to run. - JS_MaybeGC(cx); - } - return 0; -} - -int -main(int argc, const char* argv[]) -{ - JSContext* cx = NULL; - int ret; - - couch_args* args = couch_parse_args(argc, argv); - - JS_Init(); - cx = JS_NewContext(args->stack_size); - if(cx == NULL) { - JS_ShutDown(); - return 1; - } - ret = runWithContext(cx, args); - JS_DestroyContext(cx); - JS_ShutDown(); - - return ret; -} diff --git a/src/couch/priv/couch_js/86/util.cpp b/src/couch/priv/couch_js/86/util.cpp deleted file mode 100644 index b61c76ad2..000000000 --- a/src/couch/priv/couch_js/86/util.cpp +++ /dev/null @@ -1,348 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. - -#include <stdlib.h> -#include <string.h> - -#include <sstream> - -#include <jsapi.h> -#include <jsfriendapi.h> -#include <js/CharacterEncoding.h> -#include <js/Conversions.h> -#include <js/Initialization.h> -#include <js/MemoryFunctions.h> -#include <js/RegExp.h> - -#include "help.h" -#include "util.h" - -std::string -js_to_string(JSContext* cx, JS::HandleValue val) -{ - JS::AutoSaveExceptionState exc_state(cx); - JS::RootedString sval(cx); - sval = val.toString(); - - JS::UniqueChars chars(JS_EncodeStringToUTF8(cx, sval)); - if(!chars) { - JS_ClearPendingException(cx); - return std::string(); - } - - return chars.get(); -} - -bool -js_to_string(JSContext* cx, JS::HandleValue val, std::string& str) -{ - if(!val.isString()) { - return false; - } - - if(JS_GetStringLength(val.toString()) == 0) { - str = ""; - return true; - } - - std::string conv = js_to_string(cx, val); - if(!conv.size()) { - return false; - } - - str = conv; - return true; -} - -JSString* -string_to_js(JSContext* cx, const std::string& raw) -{ - JS::UTF8Chars utf8(raw.c_str(), raw.size()); - JS::UniqueTwoByteChars utf16; - size_t len; - - utf16.reset(JS::UTF8CharsToNewTwoByteCharsZ(cx, utf8, &len, js::MallocArena).get()); - if(!utf16) { - return nullptr; - } - - return JS_NewUCString(cx, std::move(utf16), len); -} - -size_t -couch_readfile(const char* file, char** outbuf_p) -{ - FILE* fp; - char fbuf[16384]; - char *buf = NULL; - char* tmp; - size_t nread = 0; - size_t buflen = 0; - - if(strcmp(file, "-") == 0) { - fp = stdin; - } else { - fp = fopen(file, "r"); - if(fp == NULL) { - fprintf(stderr, "Failed to read file: %s\n", file); - exit(3); - } - } - - while((nread = fread(fbuf, 1, 16384, fp)) > 0) { - if(buf == NULL) { - buf = new char[nread + 1]; - if(buf == NULL) { - fprintf(stderr, "Out of memory.\n"); - exit(3); - } - memcpy(buf, fbuf, nread); - } else { - tmp = new char[buflen + nread + 1]; - if(tmp == NULL) { - fprintf(stderr, "Out of memory.\n"); - exit(3); - } - memcpy(tmp, buf, buflen); - memcpy(tmp+buflen, fbuf, nread); - delete buf; - buf = tmp; - } - buflen += nread; - buf[buflen] = '\0'; - } - *outbuf_p = buf; - return buflen ; -} - -couch_args* -couch_parse_args(int argc, const char* argv[]) -{ - couch_args* args; - int i = 1; - - args = new couch_args(); - if(args == NULL) - return NULL; - - args->eval = 0; - args->stack_size = 64L * 1024L * 1024L; - args->scripts = nullptr; - - while(i < argc) { - if(strcmp("-h", argv[i]) == 0) { - DISPLAY_USAGE; - exit(0); - } else if(strcmp("-V", argv[i]) == 0) { - DISPLAY_VERSION; - exit(0); - } else if(strcmp("-S", argv[i]) == 0) { - args->stack_size = atoi(argv[++i]); - if(args->stack_size <= 0) { - fprintf(stderr, "Invalid stack size.\n"); - exit(2); - } - } else if(strcmp("--eval", argv[i]) == 0) { - args->eval = 1; - } else if(strcmp("--", argv[i]) == 0) { - i++; - break; - } else { - break; - } - i++; - } - - if(i >= argc) { - DISPLAY_USAGE; - exit(3); - } - args->scripts = argv + i; - - return args; -} - - -int -couch_fgets(char* buf, int size, FILE* fp) -{ - int n, i, c; - - if(size <= 0) return -1; - n = size - 1; - - for(i = 0; i < n && (c = getc(fp)) != EOF; i++) { - buf[i] = c; - if(c == '\n') { - i++; - break; - } - } - - buf[i] = '\0'; - return i; -} - - -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 oldbyteslen = 256; - size_t readlen = 0; - - bytes = static_cast<char*>(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. - oldbyteslen = byteslen; - byteslen *= 2; - tmp = static_cast<char*>(JS_realloc(cx, bytes, oldbyteslen, byteslen)); - if(!tmp) { - JS_free(cx, bytes); - return NULL; - } - - bytes = tmp; - } - - // Treat empty strings specially - if(used == 0) { - JS_free(cx, bytes); - return JS_NewStringCopyZ(cx, nullptr); - } - - // Shrink the buffer to the actual data size - tmp = static_cast<char*>(JS_realloc(cx, bytes, byteslen, used)); - if(!tmp) { - JS_free(cx, bytes); - return NULL; - } - bytes = tmp; - byteslen = used; - - str = string_to_js(cx, std::string(tmp)); - JS_free(cx, bytes); - return str; -} - - -void -couch_print(JSContext* cx, JS::HandleValue obj, bool use_stderr) -{ - FILE *stream = stdout; - - if (use_stderr) { - stream = stderr; - } - std::string val = js_to_string(cx, obj); - fprintf(stream, "%s\n", val.c_str()); - fflush(stream); -} - - -void -couch_error(JSContext* cx, JSErrorReport* report) -{ - if(!report) { - return; - } - - if(report->isWarning()) { - return; - } - - std::ostringstream msg; - msg << "error: " << report->message().c_str(); - - mozilla::Maybe<JSAutoRealm> ar; - JS::RootedValue exc(cx); - JS::RootedObject exc_obj(cx); - JS::RootedObject stack_obj(cx); - JS::RootedString stack_str(cx); - JS::RootedValue stack_val(cx); - JSPrincipals* principals = GetRealmPrincipals(js::GetContextRealm(cx)); - - if(!JS_GetPendingException(cx, &exc)) { - goto done; - } - - // Clear the exception before an JS method calls or the result is - // infinite, recursive error report generation. - JS_ClearPendingException(cx); - - exc_obj.set(exc.toObjectOrNull()); - stack_obj.set(JS::ExceptionStackOrNull(exc_obj)); - - if(!stack_obj) { - // Compilation errors don't have a stack - - msg << " at "; - - if(report->filename) { - msg << report->filename; - } else { - msg << "<unknown>"; - } - - if(report->lineno) { - msg << ':' << report->lineno << ':' << report->column; - } - - goto done; - } - - if(!JS::BuildStackString(cx, principals, stack_obj, &stack_str, 2)) { - goto done; - } - - stack_val.set(JS::StringValue(stack_str)); - msg << std::endl << std::endl << js_to_string(cx, stack_val).c_str(); - -done: - msg << std::endl; - fprintf(stderr, "%s", msg.str().c_str()); -} - - -void -couch_oom(JSContext* cx, void* data) -{ - fprintf(stderr, "out of memory\n"); - _Exit(1); -} - - -bool -couch_load_funcs(JSContext* cx, JS::HandleObject obj, JSFunctionSpec* funcs) -{ - JSFunctionSpec* f; - for(f = funcs; f->name; f++) { - if(!JS_DefineFunction(cx, obj, f->name.string(), f->call.op, f->nargs, f->flags)) { - fprintf(stderr, "Failed to create function: %s\n", f->name.string()); - return false; - } - } - return true; -} diff --git a/src/couch/priv/couch_js/86/util.h b/src/couch/priv/couch_js/86/util.h deleted file mode 100644 index bd7843eb9..000000000 --- a/src/couch/priv/couch_js/86/util.h +++ /dev/null @@ -1,41 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. - -#ifndef COUCHJS_UTIL_H -#define COUCHJS_UTIL_H - -#include <jsapi.h> - -typedef struct { - int eval; - int use_http; - int use_test_funs; - int stack_size; - const char** scripts; - const char* uri_file; - JSString* uri; -} couch_args; - -std::string js_to_string(JSContext* cx, JS::HandleValue val); -bool js_to_string(JSContext* cx, JS::HandleValue val, std::string& str); -JSString* string_to_js(JSContext* cx, const std::string& s); - -couch_args* couch_parse_args(int argc, const char* argv[]); -int couch_fgets(char* buf, int size, FILE* fp); -JSString* couch_readline(JSContext* cx, FILE* fp); -size_t couch_readfile(const char* file, char** outbuf_p); -void couch_print(JSContext* cx, JS::HandleValue str, bool use_stderr); -void couch_error(JSContext* cx, JSErrorReport* report); -void couch_oom(JSContext* cx, void* data); -bool couch_load_funcs(JSContext* cx, JS::HandleObject obj, JSFunctionSpec* funcs); - -#endif // Included util.h diff --git a/src/couch/priv/spawnkillable/couchspawnkillable.sh b/src/couch/priv/spawnkillable/couchspawnkillable.sh deleted file mode 100755 index f8d042e36..000000000 --- a/src/couch/priv/spawnkillable/couchspawnkillable.sh +++ /dev/null @@ -1,20 +0,0 @@ -#! /bin/sh -e - -# Licensed under the Apache License, Version 2.0 (the "License"); you may not -# use this file except in compliance with the License. You may obtain a copy of -# the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations under -# the License. - -# The purpose of this script is to echo an OS specific command before launching -# the actual process. This provides a way for Erlang to hard-kill its external -# processes. - -echo "kill -9 $$" -exec $* diff --git a/src/couch/priv/spawnkillable/couchspawnkillable_win.c b/src/couch/priv/spawnkillable/couchspawnkillable_win.c deleted file mode 100644 index 067823159..000000000 --- a/src/couch/priv/spawnkillable/couchspawnkillable_win.c +++ /dev/null @@ -1,145 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. - -// Do what 2 lines of shell script in couchspawnkillable does... -// * Create a new suspended process with the same (duplicated) standard -// handles as us. -// * Write a line to stdout, consisting of the path to ourselves, plus -// '--kill {pid}' where {pid} is the PID of the newly created process. -// * Un-suspend the new process. -// * Wait for the process to terminate. -// * Terminate with the child's exit-code. - -// Later, couch will call us with --kill and the PID, so we dutifully -// terminate the specified PID. - -#include <stdlib.h> -#include "windows.h" - -char *get_child_cmdline(int argc, char **argv) -{ - // make a new command-line, but skipping me. - // XXX - todo - spaces etc in args??? - int i; - char *p, *cmdline; - int nchars = 0; - int nthis = 1; - for (i=1;i<argc;i++) - nchars += strlen(argv[i])+1; - cmdline = p = malloc(nchars+1); - if (!cmdline) - return NULL; - for (i=1;i<argc;i++) { - nthis = strlen(argv[i]); - strncpy(p, argv[i], nthis); - p[nthis] = ' '; - p += nthis+1; - } - // Replace the last space we added above with a '\0' - cmdline[nchars-1] = '\0'; - return cmdline; -} - -// create the child process, returning 0, or the exit-code we will -// terminate with. -int create_child(int argc, char **argv, PROCESS_INFORMATION *pi) -{ - char buf[1024]; - DWORD dwcreate; - STARTUPINFO si; - char *cmdline; - if (argc < 2) - return 1; - cmdline = get_child_cmdline(argc, argv); - if (!cmdline) - return 2; - - memset(&si, 0, sizeof(si)); - si.cb = sizeof(si); - // depending on how *our* parent is started, we may or may not have - // a valid stderr stream - so although we try and duplicate it, only - // failing to duplicate stdin and stdout are considered fatal. - if (!DuplicateHandle(GetCurrentProcess(), - GetStdHandle(STD_INPUT_HANDLE), - GetCurrentProcess(), - &si.hStdInput, - 0, - TRUE, // inheritable - DUPLICATE_SAME_ACCESS) || - !DuplicateHandle(GetCurrentProcess(), - GetStdHandle(STD_OUTPUT_HANDLE), - GetCurrentProcess(), - &si.hStdOutput, - 0, - TRUE, // inheritable - DUPLICATE_SAME_ACCESS)) { - return 3; - } - DuplicateHandle(GetCurrentProcess(), - GetStdHandle(STD_ERROR_HANDLE), - GetCurrentProcess(), - &si.hStdError, - 0, - TRUE, // inheritable - DUPLICATE_SAME_ACCESS); - - si.dwFlags = STARTF_USESTDHANDLES; - dwcreate = CREATE_SUSPENDED; - if (!CreateProcess( NULL, cmdline, - NULL, - NULL, - TRUE, // inherit handles - dwcreate, - NULL, // environ - NULL, // cwd - &si, - pi)) - return 4; - return 0; -} - -// and here we go... -int main(int argc, char **argv) -{ - char out_buf[1024]; - int rc; - DWORD cbwritten; - DWORD exitcode; - PROCESS_INFORMATION pi; - if (argc==3 && strcmp(argv[1], "--kill")==0) { - HANDLE h = OpenProcess(PROCESS_TERMINATE, 0, atoi(argv[2])); - if (!h) - return 1; - if (!TerminateProcess(h, 0)) - return 2; - CloseHandle(h); - return 0; - } - // spawn the new suspended process - rc = create_child(argc, argv, &pi); - if (rc) - return rc; - // Write the 'terminate' command, which includes this PID, back to couch. - // *sob* - what about spaces etc? - sprintf_s(out_buf, sizeof(out_buf), "%s --kill %d\n", - argv[0], pi.dwProcessId); - WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), out_buf, strlen(out_buf), - &cbwritten, NULL); - // Let the child process go... - ResumeThread(pi.hThread); - // Wait for the process to terminate so we can reflect the exit code - // back to couch. - WaitForSingleObject(pi.hProcess, INFINITE); - if (!GetExitCodeProcess(pi.hProcess, &exitcode)) - return 6; - return exitcode; -} diff --git a/src/couch/priv/stats_descriptions.cfg b/src/couch/priv/stats_descriptions.cfg deleted file mode 100644 index 7c8fd94cb..000000000 --- a/src/couch/priv/stats_descriptions.cfg +++ /dev/null @@ -1,332 +0,0 @@ -%% Licensed under the Apache License, Version 2.0 (the "License"); you may not -%% use this file except in compliance with the License. You may obtain a copy of -%% the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -%% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -%% License for the specific language governing permissions and limitations under -%% the License. - -% Style guide for descriptions: Start with a lowercase letter & do not add -% a trailing full-stop / period -% Please keep this in alphabetical order - -{[couchdb, auth_cache_hits], [ - {type, counter}, - {desc, <<"number of authentication cache hits">>} -]}. -{[couchdb, auth_cache_misses], [ - {type, counter}, - {desc, <<"number of authentication cache misses">>} -]}. -{[couchdb, collect_results_time], [ - {type, histogram}, - {desc, <<"microsecond latency for calls to couch_db:collect_results/3">>} -]}. -{[couchdb, database_writes], [ - {type, counter}, - {desc, <<"number of times a database was changed">>} -]}. -{[couchdb, database_reads], [ - {type, counter}, - {desc, <<"number of times a document was read from a database">>} -]}. -{[couchdb, database_purges], [ - {type, counter}, - {desc, <<"number of times a database was purged">>} -]}. -{[couchdb, db_open_time], [ - {type, histogram}, - {desc, <<"milliseconds required to open a database">>} -]}. -{[couchdb, document_inserts], [ - {type, counter}, - {desc, <<"number of documents inserted">>} -]}. -{[couchdb, document_writes], [ - {type, counter}, - {desc, <<"number of document write operations">>} -]}. -{[couchdb, document_purges, total], [ - {type, counter}, - {desc, <<"number of total document purge operations">>} -]}. -{[couchdb, document_purges, success], [ - {type, counter}, - {desc, <<"number of successful document purge operations">>} -]}. -{[couchdb, document_purges, failure], [ - {type, counter}, - {desc, <<"number of failed document purge operations">>} -]}. -{[couchdb, local_document_writes], [ - {type, counter}, - {desc, <<"number of _local document write operations">>} -]}. -{[couchdb, httpd, bulk_docs], [ - {type, histogram}, - {desc, <<"distribution of the number of docs in _bulk_docs requests">>} -]}. -{[couchdb, httpd, bulk_requests], [ - {type, counter}, - {desc, <<"number of bulk requests">>} -]}. -{[couchdb, httpd, requests], [ - {type, counter}, - {desc, <<"number of HTTP requests">>} -]}. -{[couchdb, httpd, view_timeouts], [ - {type, counter}, - {desc, <<"number of HTTP view timeouts">>} -]}. -{[couchdb, httpd, find_timeouts], [ - {type, counter}, - {desc, <<"number of HTTP find timeouts">>} -]}. -{[couchdb, httpd, explain_timeouts], [ - {type, counter}, - {desc, <<"number of HTTP _explain timeouts">>} -]}. -{[couchdb, httpd, all_docs_timeouts], [ - {type, counter}, - {desc, <<"number of HTTP all_docs timeouts">>} -]}. -{[couchdb, httpd, partition_view_requests], [ - {type, counter}, - {desc, <<"number of partition HTTP view requests">>} -]}. -{[couchdb, httpd, partition_find_requests], [ - {type, counter}, - {desc, <<"number of partition HTTP _find requests">>} -]}. -{[couchdb, httpd, partition_explain_requests], [ - {type, counter}, - {desc, <<"number of partition HTTP _explain requests">>} -]}. -{[couchdb, httpd, partition_all_docs_requests], [ - {type, counter}, - {desc, <<"number of partition HTTP _all_docs requests">>} -]}. -{[couchdb, httpd, partition_view_timeouts], [ - {type, counter}, - {desc, <<"number of partition HTTP view timeouts">>} -]}. -{[couchdb, httpd, partition_find_timeouts], [ - {type, counter}, - {desc, <<"number of partition HTTP find timeouts">>} -]}. -{[couchdb, httpd, partition_explain_timeouts], [ - {type, counter}, - {desc, <<"number of partition HTTP _explain timeouts">>} -]}. -{[couchdb, httpd, partition_all_docs_timeouts], [ - {type, counter}, - {desc, <<"number of partition HTTP all_docs timeouts">>} -]}. -{[couchdb, httpd, temporary_view_reads], [ - {type, counter}, - {desc, <<"number of temporary view reads">>} -]}. -{[couchdb, httpd, view_reads], [ - {type, counter}, - {desc, <<"number of view reads">>} -]}. -{[couchdb, httpd, clients_requesting_changes], [ - {type, counter}, - {desc, <<"number of clients for continuous _changes">>} -]}. -{[couchdb, httpd, purge_requests], [ - {type, counter}, - {desc, <<"number of purge requests">>} -]}. -{[couchdb, httpd_request_methods, 'COPY'], [ - {type, counter}, - {desc, <<"number of HTTP COPY requests">>} -]}. -{[couchdb, httpd_request_methods, 'DELETE'], [ - {type, counter}, - {desc, <<"number of HTTP DELETE requests">>} -]}. -{[couchdb, httpd_request_methods, 'GET'], [ - {type, counter}, - {desc, <<"number of HTTP GET requests">>} -]}. -{[couchdb, httpd_request_methods, 'HEAD'], [ - {type, counter}, - {desc, <<"number of HTTP HEAD requests">>} -]}. -{[couchdb, httpd_request_methods, 'OPTIONS'], [ - {type, counter}, - {desc, <<"number of HTTP OPTIONS requests">>} -]}. -{[couchdb, httpd_request_methods, 'POST'], [ - {type, counter}, - {desc, <<"number of HTTP POST requests">>} -]}. -{[couchdb, httpd_request_methods, 'PUT'], [ - {type, counter}, - {desc, <<"number of HTTP PUT requests">>} -]}. -{[couchdb, httpd_status_codes, 200], [ - {type, counter}, - {desc, <<"number of HTTP 200 OK responses">>} -]}. -{[couchdb, httpd_status_codes, 201], [ - {type, counter}, - {desc, <<"number of HTTP 201 Created responses">>} -]}. -{[couchdb, httpd_status_codes, 202], [ - {type, counter}, - {desc, <<"number of HTTP 202 Accepted responses">>} -]}. -{[couchdb, httpd_status_codes, 204], [ - {type, counter}, - {desc, <<"number of HTTP 204 No Content responses">>} -]}. -{[couchdb, httpd_status_codes, 206], [ - {type, counter}, - {desc, <<"number of HTTP 206 Partial Content">>} -]}. -{[couchdb, httpd_status_codes, 301], [ - {type, counter}, - {desc, <<"number of HTTP 301 Moved Permanently responses">>} -]}. -{[couchdb, httpd_status_codes, 302], [ - {type, counter}, - {desc, <<"number of HTTP 302 Found responses">>} -]}. -{[couchdb, httpd_status_codes, 304], [ - {type, counter}, - {desc, <<"number of HTTP 304 Not Modified responses">>} -]}. -{[couchdb, httpd_status_codes, 400], [ - {type, counter}, - {desc, <<"number of HTTP 400 Bad Request responses">>} -]}. -{[couchdb, httpd_status_codes, 401], [ - {type, counter}, - {desc, <<"number of HTTP 401 Unauthorized responses">>} -]}. -{[couchdb, httpd_status_codes, 403], [ - {type, counter}, - {desc, <<"number of HTTP 403 Forbidden responses">>} -]}. -{[couchdb, httpd_status_codes, 404], [ - {type, counter}, - {desc, <<"number of HTTP 404 Not Found responses">>} -]}. -{[couchdb, httpd_status_codes, 405], [ - {type, counter}, - {desc, <<"number of HTTP 405 Method Not Allowed responses">>} -]}. -{[couchdb, httpd_status_codes, 406], [ - {type, counter}, - {desc, <<"number of HTTP 406 Not Acceptable responses">>} -]}. -{[couchdb, httpd_status_codes, 409], [ - {type, counter}, - {desc, <<"number of HTTP 409 Conflict responses">>} -]}. -{[couchdb, httpd_status_codes, 412], [ - {type, counter}, - {desc, <<"number of HTTP 412 Precondition Failed responses">>} -]}. -{[couchdb, httpd_status_codes, 413], [ - {type, counter}, - {desc, <<"number of HTTP 413 Request Entity Too Long responses">>} -]}. -{[couchdb, httpd_status_codes, 414], [ - {type, counter}, - {desc, <<"number of HTTP 414 Request URI Too Long responses">>} -]}. -{[couchdb, httpd_status_codes, 415], [ - {type, counter}, - {desc, <<"number of HTTP 415 Unsupported Media Type responses">>} -]}. -{[couchdb, httpd_status_codes, 416], [ - {type, counter}, - {desc, <<"number of HTTP 416 Requested Range Not Satisfiable responses">>} -]}. -{[couchdb, httpd_status_codes, 417], [ - {type, counter}, - {desc, <<"number of HTTP 417 Expectation Failed responses">>} -]}. -{[couchdb, httpd_status_codes, 500], [ - {type, counter}, - {desc, <<"number of HTTP 500 Internal Server Error responses">>} -]}. -{[couchdb, httpd_status_codes, 501], [ - {type, counter}, - {desc, <<"number of HTTP 501 Not Implemented responses">>} -]}. -{[couchdb, httpd_status_codes, 503], [ - {type, counter}, - {desc, <<"number of HTTP 503 Service unavailable responses">>} -]}. -{[couchdb, open_databases], [ - {type, counter}, - {desc, <<"number of open databases">>} -]}. -{[couchdb, open_os_files], [ - {type, counter}, - {desc, <<"number of file descriptors CouchDB has open">>} -]}. -{[couchdb, request_time], [ - {type, histogram}, - {desc, <<"length of a request inside CouchDB without MochiWeb">>} -]}. -{[couchdb, couch_server, lru_skip], [ - {type, counter}, - {desc, <<"number of couch_server LRU operations skipped">>} -]}. -{[couchdb, query_server, vdu_rejects], [ - {type, counter}, - {desc, <<"number of rejections by validate_doc_update function">>} -]}. -{[couchdb, query_server, vdu_process_time], [ - {type, histogram}, - {desc, <<"duration of validate_doc_update function calls">>} -]}. -{[pread, exceed_eof], [ - {type, counter}, - {desc, <<"number of the attempts to read beyond end of db file">>} -]}. -{[pread, exceed_limit], [ - {type, counter}, - {desc, <<"number of the attempts to read beyond set limit">>} -]}. -{[mango, unindexed_queries], [ - {type, counter}, - {desc, <<"number of mango queries that could not use an index">>} -]}. -{[mango, query_invalid_index], [ - {type, counter}, - {desc, <<"number of mango queries that generated an invalid index warning">>} -]}. -{[mango, too_many_docs_scanned], [ - {type, counter}, - {desc, <<"number of mango queries that generated an index scan warning">>} -]}. -{[mango, docs_examined], [ - {type, counter}, - {desc, <<"number of documents examined by mango queries coordinated by this node">>} -]}. -{[mango, quorum_docs_examined], [ - {type, counter}, - {desc, <<"number of documents examined by mango queries, using cluster quorum">>} -]}. -{[mango, results_returned], [ - {type, counter}, - {desc, <<"number of rows returned by mango queries">>} -]}. -{[mango, query_time], [ - {type, histogram}, - {desc, <<"length of time processing a mango query">>} -]}. -{[mango, evaluate_selector], [ - {type, counter}, - {desc, <<"number of mango selector evaluations">>} -]}. |