static int dict_insert(DICT *dict, struct object *obj, void *data) { INFUN(); if (!obj) return DICT_NULL_OBJECT; if (!data) return DICT_NULL_DATA; if (!dict) return DICT_NULL_DICT; if (dict->used && (dict->used >= dict->dict->data->num_keypairs)) { struct mapping *nmap, *tmp; nmap = allocate_mapping(dict->dict->data->num_keypairs << 1); tmp = merge_mappings(dict->dict, nmap, PIKE_ARRAY_OP_AND); free_mapping(dict->dict); free_mapping(nmap); dict->dict = tmp; } { struct svalue skey, sval, *tmp; char addr[64]; sval.type = T_OBJECT; sval.u.object = obj; sprintf(addr, "0x%X", (unsigned)data); skey.type = T_STRING; skey.u.string = make_shared_string(addr); tmp = low_mapping_lookup(dict->dict, &skey); if (tmp) { free_string(skey.u.string); OUTFUN(); return DICT_EXISTS; } mapping_insert(dict->dict, &skey, &sval); dict->used++; } OUTFUN(); return DICT_OK; }
static struct object* dict_lookup(DICT *dict, void *data) { struct svalue *obj, skey; char addr[64]; INFUN(); if (!dict || !data) return NULL; sprintf(addr, "0x%X", (unsigned)data); skey.type = T_STRING; skey.u.string = make_shared_string(addr); obj = low_mapping_lookup(dict->dict, &skey); free_string(skey.u.string); OUTFUN(); return obj->u.object; }
static void f_buf_append( INT32 args ) { struct pike_string *str; struct svalue skey, sval; /* header, value */ int slash_n = 0, cnt, num; unsigned char *pp,*ep; struct svalue *tmp; int os=0, i, j=0, l, qmark = -1; unsigned char *in, *query; if( Pike_sp[-1].type != T_STRING ) Pike_error("Wrong type of argument to append()\n"); str = Pike_sp[-1].u.string; if( str->len >= BUF->free ) { pop_n_elems(args); push_int(413); /* Request Entity Too Large */ return; } MEMCPY( BUF->pos, str->str, str->len ); for( ep = (BUF->pos + str->len), pp = MAX(BUF->data, BUF->pos-3); pp < ep && slash_n < 2; pp++ ) if( *pp == '\n' ) slash_n++; else if( *pp != '\r' ) slash_n=0; BUF->free -= str->len; BUF->pos += str->len; BUF->pos[0] = 0; pop_n_elems( args ); if( slash_n != 2 ) { /* need more data */ push_int( 0 ); return; } skey.type = sval.type = T_STRING; sval.u.string = make_shared_binary_string( (char *)pp, BUF->pos - pp); mapping_insert(BUF->other, SVAL(data), &sval); /* data */ free_string(sval.u.string); in = BUF->data; l = pp - BUF->data; /* find method */ for( i = 0; i < l; i++ ) { if( in[i] == ' ' ) break; else if(in[i] == '\n') { push_int( 400 ); /* Bad Request */ return; } } sval.u.string = make_shared_binary_string((char *)in, i); mapping_insert(BUF->other, SVAL(method), &sval); free_string(sval.u.string); i++; in += i; l -= i; /* find file */ for( i = 0; i < l; i++ ) { if(in[i] == ' ') { break; } else if(in[i] == '\n') { push_int( 400 ); /* Bad Request */ return; } } sval.u.string = make_shared_binary_string((char *)in, i); mapping_insert(BUF->other, SVAL(raw_url), &sval); free_string(sval.u.string); /* Decode file part and return pointer to query, if any */ query = char_decode_url(in, i); /* Decoded, query-less file up to the first \0 */ sval.u.string = make_shared_string((char *)in); mapping_insert(BUF->other, SVAL(file), &sval); free_string(sval.u.string); if(query != NULL) { /* Store the query string */ sval.u.string = make_shared_binary_string((char *)query, i - (query-in)); /* Also up to first null */ mapping_insert(BUF->other, SVAL(query), &sval); free_string(sval.u.string); } i++; in += i; l -= i; /* find protocol */ for( i = 0; i < l; i++ ) { if( in[i] == '\n' ) break; else if(in[i] == ' ') { push_int( 400 ); /* Bad Request */ return; } } if( in[i-1] != '\r' ) i++; sval.u.string = make_shared_binary_string((char *)in, i-1); mapping_insert(BUF->other, SVAL(protocol), &sval); free_string(sval.u.string); in += i; l -= i; if( *in == '\n' ) (in++),(l--); for(i = 0; i < l; i++) { if(in[i] >= 'A' && in[i] <= 'Z') in[i] |= 32; /* Lowercasing the header */ else if( in[i] == ':' ) { /* in[os..i-1] == the header */ skey.u.string = make_shared_binary_string((char*)in+os, i - os); os = i+1; while(in[os]==' ') os++; /* Remove initial spaces */ for(j=os;j<l;j++) if( in[j] == '\n' || in[j]=='\r') break; if((tmp = low_mapping_lookup(BUF->headers, &skey)) && tmp->type == T_STRING) { int len = j - os + 1; int len2 = len +tmp->u.string->len; sval.u.string = begin_shared_string(len2); MEMCPY(sval.u.string->str, tmp->u.string->str, tmp->u.string->len); sval.u.string->str[tmp->u.string->len] = ','; MEMCPY(sval.u.string->str + tmp->u.string->len + 1, (char*)in + os, len); sval.u.string = end_shared_string(sval.u.string); } else { sval.u.string = make_shared_binary_string((char*)in + os, j - os); } mapping_insert(BUF->headers, &skey, &sval); if( in[j+1] == '\n' ) j++; os = j+1; i = j; free_string(sval.u.string); free_string(skey.u.string); } } push_int(1); }
/* This function parses the query string */ static void f_parse_query_string( INT32 args ) { struct pike_string *query; /* Query string to parse */ struct svalue *exist, skey, sval; /* svalues used */ struct mapping *variables; /* Mapping to store vars in */ unsigned char *ptr; /* Pointer to current char in loop */ unsigned char *name; /* Pointer to beginning of name */ unsigned char *equal; /* Pointer to the equal sign */ unsigned char *end; /* Pointer to the ending null char */ int namelen, valulen; /* Length of the current name and value */ get_all_args("Caudium.parse_query_string", args, "%S%m", &query, &variables); skey.type = sval.type = T_STRING; /* end of query string */ end = (unsigned char *)(query->str + query->len); name = ptr = (unsigned char *)query->str; equal = NULL; for(; ptr <= end; ptr++) { switch(*ptr) { case '=': /* Allow an unencoded '=' in the value. It's invalid but... */ if(equal == NULL) equal=ptr; break; case '\0': if(ptr != end) continue; case ';': /* It's recommended to support ';' instead of '&' in query strings... */ case '&': if(equal == NULL) { /* value less variable, we can ignore this */ name = ptr+1; break; } namelen = equal - name; valulen = ptr - ++equal; skey.u.string = url_decode(name, namelen, 0); if (skey.u.string == NULL) { /* OOM. Bail out */ Pike_error("Caudium.parse_query_string(): Out of memory in url_decode().\n"); } exist = low_mapping_lookup(variables, &skey); if(exist == NULL || exist->type != T_STRING) { sval.u.string = url_decode(equal, valulen, 0); if (sval.u.string == NULL) { /* OOM. Bail out */ Pike_error("Caudium.parse_query_string(): " "Out of memory in url_decode().\n"); } } else { /* Add strings separed with '\0'... */ struct pike_string *tmp; tmp = url_decode(equal, valulen, 1); if (tmp == NULL) { Pike_error("Caudium.parse_query_string(): " "Out of memory in url_decode().\n"); } sval.u.string = add_shared_strings(exist->u.string, tmp); free_string(tmp); } mapping_insert(variables, &skey, &sval); free_string(skey.u.string); free_string(sval.u.string); /* Reset pointers */ equal = NULL; name = ptr+1; } } pop_n_elems(args); }