static int bind_table_entry(void *data, const char *key, const char *value) { /* Don't allow anything to become a string that has invalid utf-8, because Lily's string type assumes valid utf-8. */ if (lily_is_valid_utf8(key) == 0 || lily_is_valid_utf8(value) == 0) return TRUE; struct table_bind_data *d = data; lily_value *elem_key = lily_new_string(key); lily_value *elem_raw_value = lily_new_string(value); lily_value *elem_value = bind_tainted_of(elem_raw_value); apache_add_unique_hash_entry(d->sipkey, d->hash_val, elem_key, elem_value); return TRUE; }
lily_value *lily_new_value_of_string_raw(const char *str) { lily_value *v = lily_malloc(sizeof(lily_value)); lily_string_val *sv = lily_new_string(str); sv->refcount++; v->flags = LILY_STRING_ID | VAL_IS_DEREFABLE; v->value.string = sv; return v; }
/** define getenv(name: String): Option[String] Search the environment for `name`, returning either a `Some` with the contents, or `None`. Internally, this is a wrapper over C's getenv. */ static void lily_sys_getenv(lily_state *s) { char *env = getenv(lily_arg_string_raw(s, 0)); if (env) { lily_variant_val *variant = lily_new_variant(1); lily_variant_set_string(variant, 0, lily_new_string(env)); lily_return_variant(s, LILY_SOME_ID, variant); } else lily_return_empty_variant(s, LILY_NONE_ID); }
/** var argv: List[String] This contains arguments sent to the program through the command-line. If Lily was not invoked from the command-line (ex: mod_lily), then this is empty. */ static void *load_var_argv(lily_options *options, uint16_t *unused) { int opt_argc; char **opt_argv = lily_op_get_argv(options, &opt_argc); lily_list_val *lv = lily_new_list(opt_argc); int i; for (i = 0;i < opt_argc;i++) lily_list_set_string(lv, i, lily_new_string(opt_argv[i])); return lily_new_value_of_list(lv); }
/** var post: Hash[String, Tainted[String]] This contains key+value pairs that were sent to the server as POST variables. Any pair that has a key or a value that is not valid utf-8 will not be present. */ static lily_value *load_var_post(lily_options *options, uint16_t *unused) { lily_value *v = lily_new_empty_value(); lily_move_hash_f(MOVE_DEREF_NO_GC, v, lily_new_hash_val()); lily_hash_val *hash_val = v->value.hash; request_rec *r = (request_rec *)options->data; apr_array_header_t *pairs; apr_off_t len; apr_size_t size; char *buffer; /* Credit: I found out how to use this by reading httpd 2.4's mod_lua (specifically req_parsebody of lua_request.c). */ int res = ap_parse_form_data(r, NULL, &pairs, -1, 1024 * 8); if (res == OK) { while (pairs && !apr_is_empty_array(pairs)) { ap_form_pair_t *pair = (ap_form_pair_t *) apr_array_pop(pairs); if (lily_is_valid_utf8(pair->name) == 0) continue; apr_brigade_length(pair->value, 1, &len); size = (apr_size_t) len; buffer = lily_malloc(size + 1); if (lily_is_valid_utf8(buffer) == 0) { lily_free(buffer); continue; } apr_brigade_flatten(pair->value, buffer, &size); buffer[len] = 0; lily_value *elem_key = lily_new_string(pair->name); /* Give the buffer to the value to save memory. */ lily_value *elem_raw_value = lily_new_string_take(buffer); lily_value *elem_value = bind_tainted_of(elem_raw_value); apache_add_unique_hash_entry(options->sipkey, hash_val, elem_key, elem_value); } } return v; }
lily_bytestring_val *lily_new_bytestring(const char *source) { return (lily_bytestring_val *)lily_new_string(source); }