summaryrefslogtreecommitdiff
path: root/source4/scripting/ejs/literal.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/scripting/ejs/literal.c')
-rw-r--r--source4/scripting/ejs/literal.c797
1 files changed, 0 insertions, 797 deletions
diff --git a/source4/scripting/ejs/literal.c b/source4/scripting/ejs/literal.c
deleted file mode 100644
index 8307c211d3..0000000000
--- a/source4/scripting/ejs/literal.c
+++ /dev/null
@@ -1,797 +0,0 @@
-/*
- * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
- * Michael Clark <michael@metaparadigm.com>
- * Copyright (c) 2006 Derrell Lipman
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See COPYING for details.
- *
- * Derrell Lipman:
- * This version is modified from the original. It has been modified to
- * natively use EJS variables rather than the original C object interface, and
- * to use the talloc() family of functions for memory allocation.
- */
-
-#include "includes.h"
-#include "scripting/ejs/smbcalls.h"
-
-enum json_tokener_error {
- json_tokener_success,
- json_tokener_error_oom, /* out of memory */
- json_tokener_error_parse_unexpected,
- json_tokener_error_parse_null,
- json_tokener_error_parse_date,
- json_tokener_error_parse_boolean,
- json_tokener_error_parse_number,
- json_tokener_error_parse_array,
- json_tokener_error_parse_object,
- json_tokener_error_parse_string,
- json_tokener_error_parse_comment,
- json_tokener_error_parse_eof
-};
-
-enum json_tokener_state {
- json_tokener_state_eatws,
- json_tokener_state_start,
- json_tokener_state_finish,
- json_tokener_state_null,
- json_tokener_state_date,
- json_tokener_state_comment_start,
- json_tokener_state_comment,
- json_tokener_state_comment_eol,
- json_tokener_state_comment_end,
- json_tokener_state_string,
- json_tokener_state_string_escape,
- json_tokener_state_escape_unicode,
- json_tokener_state_boolean,
- json_tokener_state_number,
- json_tokener_state_array,
- json_tokener_state_datelist,
- json_tokener_state_array_sep,
- json_tokener_state_datelist_sep,
- json_tokener_state_object,
- json_tokener_state_object_field_start,
- json_tokener_state_object_field,
- json_tokener_state_object_field_end,
- json_tokener_state_object_value,
- json_tokener_state_object_sep
-};
-
-enum date_field {
- date_field_year,
- date_field_month,
- date_field_day,
- date_field_hour,
- date_field_minute,
- date_field_second,
- date_field_millisecond
-};
-
-struct json_tokener
-{
- char *source;
- int pos;
- void *ctx;
- void *pb;
-};
-
-static const char *json_number_chars = "0123456789.+-e";
-static const char *json_hex_chars = "0123456789abcdef";
-
-#define hexdigit(x) (((x) <= '9') ? (x) - '0' : ((x) & 7) + 9)
-
-extern struct MprVar json_tokener_parse(char *s);
-static struct MprVar json_tokener_do_parse(struct json_tokener *this,
- enum json_tokener_error *err_p);
-
-/*
- * literal_to_var() parses a string into an ejs variable. The ejs
- * variable is returned. Upon error, the javascript variable will be
- * `undefined`. This was created for parsing JSON, but is generally useful
- * for parsing the literal forms of objects and arrays, since ejs doesn't
- * procide that functionality.
- */
-int literal_to_var(int eid, int argc, char **argv)
-{
- struct json_tokener tok;
- struct MprVar obj;
- enum json_tokener_error err = json_tokener_success;
-
- if (argc != 1) {
- ejsSetErrorMsg(eid,
- "literal_to_var() requires one parameter: "
- "the string to be parsed.");
- return -1;
- }
-
- tok.source = argv[0];
- tok.pos = 0;
- tok.ctx = talloc_new(mprMemCtx());
- if (tok.ctx == NULL) {
- mpr_Return(eid, mprCreateUndefinedVar());
- return 0;
- }
- tok.pb = talloc_zero_size(tok.ctx, 1);
- if (tok.pb == NULL) {
- mpr_Return(eid, mprCreateUndefinedVar());
- return 0;
- }
- obj = json_tokener_do_parse(&tok, &err);
- talloc_free(tok.pb);
- if (err != json_tokener_success) {
- mprDestroyVar(&obj);
- mpr_Return(eid, mprCreateUndefinedVar());
- return 0;
- }
- mpr_Return(eid, obj);
- return 0;
-}
-
-static void *append_string(void *ctx,
- char *orig,
- char *append,
- int size)
-{
- if (!orig) {
- return talloc_strndup(ctx, append, size);
- }
-
- return talloc_strndup_append(orig, append, size);
-}
-
-
-static struct MprVar json_tokener_do_parse(struct json_tokener *this,
- enum json_tokener_error *err_p)
-{
- enum json_tokener_state state;
- enum json_tokener_state saved_state;
- enum date_field date_field;
- struct MprVar current = mprCreateUndefinedVar();
- struct MprVar tempObj;
- struct MprVar obj;
- enum json_tokener_error err = json_tokener_success;
- char date_script[] = "JSON_Date.create(0);";
- char *obj_field_name = NULL;
- char *emsg = NULL;
- char quote_char;
- int deemed_double;
- int start_offset;
- char c;
-
- state = json_tokener_state_eatws;
- saved_state = json_tokener_state_start;
-
-
- do {
- c = this->source[this->pos];
- switch(state) {
-
- case json_tokener_state_eatws:
- if(isspace(c)) {
- this->pos++;
- } else if(c == '/') {
- state = json_tokener_state_comment_start;
- start_offset = this->pos++;
- } else {
- state = saved_state;
- }
- break;
-
- case json_tokener_state_start:
- switch(c) {
- case '{':
- state = json_tokener_state_eatws;
- saved_state = json_tokener_state_object;
- current = mprObject(NULL);
- this->pos++;
- break;
- case '[':
- state = json_tokener_state_eatws;
- saved_state = json_tokener_state_array;
- current = mprArray(NULL);
- this->pos++;
- break;
- case 'N':
- case 'n':
- start_offset = this->pos++;
- if (this->source[this->pos] == 'e') {
- state = json_tokener_state_date;
- } else {
- state = json_tokener_state_null;
- }
- break;
- case '"':
- case '\'':
- quote_char = c;
- talloc_free(this->pb);
- this->pb = talloc_zero_size(this->ctx, 1);
- if (this->pb == NULL) {
- *err_p = json_tokener_error_oom;
- goto out;
- }
- state = json_tokener_state_string;
- start_offset = ++this->pos;
- break;
- case 'T':
- case 't':
- case 'F':
- case 'f':
- state = json_tokener_state_boolean;
- start_offset = this->pos++;
- break;
-#if defined(__GNUC__)
- case '0' ... '9':
-#else
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
-#endif
- case '-':
- deemed_double = 0;
- state = json_tokener_state_number;
- start_offset = this->pos++;
- break;
- default:
- err = json_tokener_error_parse_unexpected;
- goto out;
- }
- break;
-
- case json_tokener_state_finish:
- goto out;
-
- case json_tokener_state_null:
- if(strncasecmp("null",
- this->source + start_offset,
- this->pos - start_offset)) {
- *err_p = json_tokener_error_parse_null;
- mprDestroyVar(&current);
- return mprCreateUndefinedVar();
- }
-
- if(this->pos - start_offset == 4) {
- mprDestroyVar(&current);
- current = mprCreateNullVar();
- saved_state = json_tokener_state_finish;
- state = json_tokener_state_eatws;
- } else {
- this->pos++;
- }
- break;
-
- case json_tokener_state_date:
- if (this->pos - start_offset <= 18) {
- if (strncasecmp("new Date(Date.UTC(",
- this->source + start_offset,
- this->pos - start_offset)) {
- *err_p = json_tokener_error_parse_date;
- mprDestroyVar(&current);
- return mprCreateUndefinedVar();
- } else {
- this->pos++;
- break;
- }
- }
-
- this->pos--; /* we went one too far */
- state = json_tokener_state_eatws;
- saved_state = json_tokener_state_datelist;
-
- /* Create a JsonDate object */
- if (ejsEvalScript(0,
- date_script,
- &tempObj,
- &emsg) != 0) {
- *err_p = json_tokener_error_parse_date;
- mprDestroyVar(&current);
- return mprCreateUndefinedVar();
- }
- mprDestroyVar(&current);
- mprCopyVar(&current, &tempObj, MPR_DEEP_COPY);
- date_field = date_field_year;
- break;
-
- case json_tokener_state_comment_start:
- if(c == '*') {
- state = json_tokener_state_comment;
- } else if(c == '/') {
- state = json_tokener_state_comment_eol;
- } else {
- err = json_tokener_error_parse_comment;
- goto out;
- }
- this->pos++;
- break;
-
- case json_tokener_state_comment:
- if(c == '*') state = json_tokener_state_comment_end;
- this->pos++;
- break;
-
- case json_tokener_state_comment_eol:
- if(c == '\n') {
- state = json_tokener_state_eatws;
- }
- this->pos++;
- break;
-
- case json_tokener_state_comment_end:
- if(c == '/') {
- state = json_tokener_state_eatws;
- } else {
- state = json_tokener_state_comment;
- }
- this->pos++;
- break;
-
- case json_tokener_state_string:
- if(c == quote_char) {
- this->pb = append_string(
- this->ctx,
- this->pb,
- this->source + start_offset,
- this->pos - start_offset);
- if (this->pb == NULL) {
- err = json_tokener_error_oom;
- goto out;
- }
- current = mprString(this->pb);
- saved_state = json_tokener_state_finish;
- state = json_tokener_state_eatws;
- } else if(c == '\\') {
- saved_state = json_tokener_state_string;
- state = json_tokener_state_string_escape;
- }
- this->pos++;
- break;
-
- case json_tokener_state_string_escape:
- switch(c) {
- case '"':
- case '\\':
- this->pb = append_string(
- this->ctx,
- this->pb,
- this->source + start_offset,
- this->pos - start_offset - 1);
- if (this->pb == NULL) {
- err = json_tokener_error_oom;
- goto out;
- }
- start_offset = this->pos++;
- state = saved_state;
- break;
- case 'b':
- case 'n':
- case 'r':
- case 't':
- this->pb = append_string(
- this->ctx,
- this->pb,
- this->source + start_offset,
- this->pos - start_offset - 1);
- if (this->pb == NULL) {
- err = json_tokener_error_oom;
- goto out;
- }
- if (c == 'b') {
- /*
- * second param to append_string()
- * gets temporarily modified; can't
- * pass string constant.
- */
- char buf[] = "\b";
- this->pb = append_string(this->ctx,
- this->pb,
- buf,
- 1);
- if (this->pb == NULL) {
- err = json_tokener_error_oom;
- goto out;
- }
- } else if (c == 'n') {
- char buf[] = "\n";
- this->pb = append_string(this->ctx,
- this->pb,
- buf,
- 1);
- if (this->pb == NULL) {
- err = json_tokener_error_oom;
- goto out;
- }
- } else if (c == 'r') {
- char buf[] = "\r";
- this->pb = append_string(this->ctx,
- this->pb,
- buf,
- 1);
- if (this->pb == NULL) {
- err = json_tokener_error_oom;
- goto out;
- }
- } else if (c == 't') {
- char buf[] = "\t";
- this->pb = append_string(this->ctx,
- this->pb,
- buf,
- 1);
- if (this->pb == NULL) {
- err = json_tokener_error_oom;
- goto out;
- }
- }
- start_offset = ++this->pos;
- state = saved_state;
- break;
- case 'u':
- this->pb = append_string(
- this->ctx,
- this->pb,
- this->source + start_offset,
- this->pos - start_offset - 1);
- if (this->pb == NULL) {
- err = json_tokener_error_oom;
- goto out;
- }
- start_offset = ++this->pos;
- state = json_tokener_state_escape_unicode;
- break;
- default:
- err = json_tokener_error_parse_string;
- goto out;
- }
- break;
-
- case json_tokener_state_escape_unicode:
- if(strchr(json_hex_chars, c)) {
- this->pos++;
- if(this->pos - start_offset == 4) {
- unsigned char utf_out[3];
- unsigned int ucs_char =
- (hexdigit(*(this->source + start_offset)) << 12) +
- (hexdigit(*(this->source + start_offset + 1)) << 8) +
- (hexdigit(*(this->source + start_offset + 2)) << 4) +
- hexdigit(*(this->source + start_offset + 3));
- if (ucs_char < 0x80) {
- utf_out[0] = ucs_char;
- this->pb = append_string(
- this->ctx,
- this->pb,
- (char *) utf_out,
- 1);
- if (this->pb == NULL) {
- err = json_tokener_error_oom;
- goto out;
- }
- } else if (ucs_char < 0x800) {
- utf_out[0] = 0xc0 | (ucs_char >> 6);
- utf_out[1] = 0x80 | (ucs_char & 0x3f);
- this->pb = append_string(
- this->ctx,
- this->pb,
- (char *) utf_out,
- 2);
- if (this->pb == NULL) {
- err = json_tokener_error_oom;
- goto out;
- }
- } else {
- utf_out[0] = 0xe0 | (ucs_char >> 12);
- utf_out[1] = 0x80 | ((ucs_char >> 6) & 0x3f);
- utf_out[2] = 0x80 | (ucs_char & 0x3f);
- this->pb = append_string(
- this->ctx,
- this->pb,
- (char *) utf_out,
- 3);
- if (this->pb == NULL) {
- err = json_tokener_error_oom;
- goto out;
- }
- }
- start_offset = this->pos;
- state = saved_state;
- }
- } else {
- err = json_tokener_error_parse_string;
- goto out;
- }
- break;
-
- case json_tokener_state_boolean:
- if(strncasecmp("true", this->source + start_offset,
- this->pos - start_offset) == 0) {
- if(this->pos - start_offset == 4) {
- current = mprCreateBoolVar(1);
- saved_state = json_tokener_state_finish;
- state = json_tokener_state_eatws;
- } else {
- this->pos++;
- }
- } else if(strncasecmp("false", this->source + start_offset,
- this->pos - start_offset) == 0) {
- if(this->pos - start_offset == 5) {
- current = mprCreateBoolVar(0);
- saved_state = json_tokener_state_finish;
- state = json_tokener_state_eatws;
- } else {
- this->pos++;
- }
- } else {
- err = json_tokener_error_parse_boolean;
- goto out;
- }
- break;
-
- case json_tokener_state_number:
- if(!c || !strchr(json_number_chars, c)) {
- int numi;
- double numd;
- char *tmp = talloc_strndup(
- this->ctx,
- this->source + start_offset,
- this->pos - start_offset);
- if (tmp == NULL) {
- err = json_tokener_error_oom;
- goto out;
- }
- if(!deemed_double && sscanf(tmp, "%d", &numi) == 1) {
- current = mprCreateIntegerVar(numi);
- } else if(deemed_double && sscanf(tmp, "%lf", &numd) == 1) {
- current = mprCreateFloatVar(numd);
- } else {
- talloc_free(tmp);
- err = json_tokener_error_parse_number;
- goto out;
- }
- talloc_free(tmp);
- saved_state = json_tokener_state_finish;
- state = json_tokener_state_eatws;
- } else {
- if(c == '.' || c == 'e') deemed_double = 1;
- this->pos++;
- }
- break;
-
- case json_tokener_state_array:
- if(c == ']') {
- this->pos++;
- saved_state = json_tokener_state_finish;
- state = json_tokener_state_eatws;
- } else {
- int oldlen;
- char idx[16];
-
- obj = json_tokener_do_parse(this, &err);
- if (err != json_tokener_success) {
- goto out;
- }
- oldlen = mprToInt(mprGetProperty(&current,
- "length",
- NULL));
- mprItoa(oldlen, idx, sizeof(idx));
- mprSetVar(&current, idx, obj);
- saved_state = json_tokener_state_array_sep;
- state = json_tokener_state_eatws;
- }
- break;
-
- case json_tokener_state_datelist:
- if(c == ')') {
- if (this->source[this->pos+1] == ')') {
- this->pos += 2;
- saved_state = json_tokener_state_finish;
- state = json_tokener_state_eatws;
- } else {
- err = json_tokener_error_parse_date;
- goto out;
- }
- } else {
- obj = json_tokener_do_parse(this, &err);
- if (err != json_tokener_success) {
- goto out;
- }
-
- /* date list items must be integers */
- if (obj.type != MPR_TYPE_INT) {
- err = json_tokener_error_parse_date;
- goto out;
- }
-
- switch(date_field) {
- case date_field_year:
- mprSetVar(&current, "year", obj);
- break;
- case date_field_month:
- mprSetVar(&current, "month", obj);
- break;
- case date_field_day:
- mprSetVar(&current, "day", obj);
- break;
- case date_field_hour:
- mprSetVar(&current, "hour", obj);
- break;
- case date_field_minute:
- mprSetVar(&current, "minute", obj);
- break;
- case date_field_second:
- mprSetVar(&current, "second", obj);
- break;
- case date_field_millisecond:
- mprSetVar(&current, "millisecond", obj);
- break;
- default:
- err = json_tokener_error_parse_date;
- goto out;
- }
-
- /* advance to the next date field */
- date_field++;
-
- saved_state = json_tokener_state_datelist_sep;
- state = json_tokener_state_eatws;
- }
- break;
-
- case json_tokener_state_array_sep:
- if(c == ']') {
- this->pos++;
- saved_state = json_tokener_state_finish;
- state = json_tokener_state_eatws;
- } else if(c == ',') {
- this->pos++;
- saved_state = json_tokener_state_array;
- state = json_tokener_state_eatws;
- } else {
- *err_p = json_tokener_error_parse_array;
- mprDestroyVar(&current);
- return mprCreateUndefinedVar();
- }
- break;
-
- case json_tokener_state_datelist_sep:
- if(c == ')') {
- if (this->source[this->pos+1] == ')') {
- this->pos += 2;
- saved_state = json_tokener_state_finish;
- state = json_tokener_state_eatws;
- } else {
- err = json_tokener_error_parse_date;
- goto out;
- }
- } else if(c == ',') {
- this->pos++;
- saved_state = json_tokener_state_datelist;
- state = json_tokener_state_eatws;
- } else {
- *err_p = json_tokener_error_parse_date;
- mprDestroyVar(&current);
- return mprCreateUndefinedVar();
- }
- break;
-
- case json_tokener_state_object:
- state = json_tokener_state_object_field_start;
- start_offset = this->pos;
- break;
-
- case json_tokener_state_object_field_start:
- if(c == '}') {
- this->pos++;
- saved_state = json_tokener_state_finish;
- state = json_tokener_state_eatws;
- } else if (c == '"' || c == '\'') {
- quote_char = c;
- talloc_free(this->pb);
- this->pb = talloc_zero_size(this->ctx, 1);
- if (this->pb == NULL) {
- *err_p = json_tokener_error_oom;
- goto out;
- }
- state = json_tokener_state_object_field;
- start_offset = ++this->pos;
- } else {
- err = json_tokener_error_parse_object;
- goto out;
- }
- break;
-
- case json_tokener_state_object_field:
- if(c == quote_char) {
- this->pb = append_string(
- this->ctx,
- this->pb,
- this->source + start_offset,
- this->pos - start_offset);
- if (this->pb == NULL) {
- err = json_tokener_error_oom;
- goto out;
- }
- obj_field_name = talloc_strdup(this->ctx,
- this->pb);
- if (obj_field_name == NULL) {
- err = json_tokener_error_oom;
- goto out;
- }
- saved_state = json_tokener_state_object_field_end;
- state = json_tokener_state_eatws;
- } else if(c == '\\') {
- saved_state = json_tokener_state_object_field;
- state = json_tokener_state_string_escape;
- }
- this->pos++;
- break;
-
- case json_tokener_state_object_field_end:
- if(c == ':') {
- this->pos++;
- saved_state = json_tokener_state_object_value;
- state = json_tokener_state_eatws;
- } else {
- *err_p = json_tokener_error_parse_object;
- mprDestroyVar(&current);
- return mprCreateUndefinedVar();
- }
- break;
-
- case json_tokener_state_object_value:
- obj = json_tokener_do_parse(this, &err);
- if (err != json_tokener_success) {
- goto out;
- }
- mprSetVar(&current, obj_field_name, obj);
- talloc_free(obj_field_name);
- obj_field_name = NULL;
- saved_state = json_tokener_state_object_sep;
- state = json_tokener_state_eatws;
- break;
-
- case json_tokener_state_object_sep:
- if(c == '}') {
- this->pos++;
- saved_state = json_tokener_state_finish;
- state = json_tokener_state_eatws;
- } else if(c == ',') {
- this->pos++;
- saved_state = json_tokener_state_object;
- state = json_tokener_state_eatws;
- } else {
- err = json_tokener_error_parse_object;
- goto out;
- }
- break;
-
- }
- } while(c);
-
- if(state != json_tokener_state_finish &&
- saved_state != json_tokener_state_finish)
- err = json_tokener_error_parse_eof;
-
-out:
- talloc_free(obj_field_name);
- if(err == json_tokener_success) {
- return current;
- } else {
- mprDestroyVar(&current);
- *err_p = err;
- return mprCreateUndefinedVar();
- }
-}
-
-
-void smb_setup_ejs_literal(void)
-{
- ejsDefineStringCFunction(-1,
- "literal_to_var",
- literal_to_var,
- NULL,
- MPR_VAR_SCRIPT_HANDLE);
-}