lily_literal *lily_get_double_literal(lily_symtab *symtab, double dbl_val) { lily_literal *iter = first_lit_of(symtab->literals, VAL_IS_DOUBLE); while (iter) { if (iter->value.doubleval == dbl_val) return iter; int next = iter->next_index; if (next == 0) break; else iter = (lily_literal *)lily_vs_nth(symtab->literals, next); } if (iter) iter->next_index = lily_vs_pos(symtab->literals); lily_literal *v = (lily_literal *)lily_new_empty_value(); v->flags = VAL_IS_DOUBLE; v->reg_spot = lily_vs_pos(symtab->literals); v->next_index = 0; v->value.doubleval = dbl_val; lily_vs_push(symtab->literals, (lily_value *)v); return (lily_literal *)v; }
lily_literal *lily_get_string_literal(lily_symtab *symtab, const char *want_string) { lily_literal *iter = first_lit_of(symtab->literals, VAL_IS_STRING); int want_string_len = strlen(want_string); while (iter) { if (iter->value.string->size == want_string_len && strcmp(iter->value.string->string, want_string) == 0) return iter; int next = iter->next_index; if (next == 0) break; else iter = (lily_literal *)lily_vs_nth(symtab->literals, next); } if (iter) iter->next_index = lily_vs_pos(symtab->literals); lily_literal *v = (lily_literal *)lily_new_empty_value(); v->flags = VAL_IS_STRING; v->reg_spot = lily_vs_pos(symtab->literals); v->next_index = 0; v->value.string = lily_new_raw_string(want_string); /* Manual ref, because the string isn't being moved/assigned anywhere. */ v->value.string->refcount++; lily_vs_push(symtab->literals, (lily_value *)v); return (lily_literal *)v; }
lily_literal *lily_get_integer_literal(lily_symtab *symtab, int64_t int_val) { lily_literal *iter = first_lit_of(symtab->literals, VAL_IS_INTEGER); while (iter) { if (iter->value.integer == int_val) return iter; int next = iter->next_index; if (next == 0) break; else iter = (lily_literal *)lily_vs_nth(symtab->literals, next); } if (iter) iter->next_index = lily_vs_pos(symtab->literals); lily_literal *v = (lily_literal *)lily_new_empty_value(); v->flags = VAL_IS_INTEGER; v->reg_spot = lily_vs_pos(symtab->literals); v->next_index = 0; v->value.integer = int_val; lily_vs_push(symtab->literals, (lily_value *)v); return (lily_literal *)v; }
/** var httpmethod: String This is the method that was used to make the request to the server. Common values are "GET", and "POST". */ static lily_value *load_var_httpmethod(lily_options *options, uint16_t *unused) { lily_value *v = lily_new_empty_value(); request_rec *r = (request_rec *)options->data; lily_move_string(v, lily_new_raw_string(r->method)); return v; }
/** package server This package is registered when Lily is run by Apache through mod_lily. This package provides Lily with information inside of Apache (such as POST), as well as functions for sending data through the Apache server. */ lily_value *bind_tainted_of(lily_value *input) { lily_instance_val *iv = lily_new_instance_val(); iv->values = lily_malloc(1 * sizeof(lily_value *)); iv->instance_id = SYM_CLASS_TAINTED; iv->values[0] = input; lily_value *result = lily_new_empty_value(); lily_move_instance_f(MOVE_DEREF_NO_GC, result, iv); return result; }
static lily_value *bind_table_as(lily_options *options, apr_table_t *table, char *name) { lily_value *v = lily_new_empty_value(); lily_move_hash_f(MOVE_DEREF_NO_GC, v, lily_new_hash_val()); struct table_bind_data data; data.hash_val = v->value.hash; data.sipkey = options->sipkey; apr_table_do(bind_table_entry, &data, table, NULL); return v; }
/* Literals and defined functions are both immutable, so they occupy the same general. This stores a function in their shared area. */ static void store_function(lily_symtab *symtab, lily_var *func_var, lily_function_val *func_val, lily_module_entry *module) { /* This is done so that lily_debug can print line numbers. */ func_val->line_num = func_var->line_num; func_val->module = module; lily_value *v = lily_new_empty_value(); v->flags = VAL_IS_FUNCTION; v->value.function = func_val; lily_vs_push(symtab->literals, v); }
/** 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_literal *make_variant_default(lily_symtab *symtab, lily_variant_class *variant) { lily_instance_val *iv = lily_new_instance_val_n_of(0, variant->cls_id); iv->num_values = 0; lily_literal *v = (lily_literal *)lily_new_empty_value(); /* This value isn't interesting, but it might be swapped out with a value that is. */ v->flags = VAL_IS_ENUM | VAL_IS_GC_SPECULATIVE; v->next_index = 0; v->reg_spot = lily_vs_pos(symtab->literals); v->value.instance = iv; /* Like with literals, fix the refcount so it's free'd later. */ iv->refcount = 1; lily_vs_push(symtab->literals, (lily_value *)v); return v; }