void t17_merge(){ INIT_LOCAL(); onion_dict *a=onion_dict_from_json("{\"hello\":\"world\"}"); onion_dict *b=onion_dict_from_json("{\"bye\":\"_world_\", \"sub\": { \"hello\": \"world!\" } }"); onion_dict_merge(a,b); FAIL_IF_NOT_EQUAL_STR(onion_dict_get(a,"bye"), "_world_"); FAIL_IF_NOT_EQUAL_STR(onion_dict_rget(a,"sub","hello",NULL), "world!"); onion_dict_free(b); FAIL_IF_NOT_EQUAL_STR(onion_dict_rget(a,"sub","hello",NULL), "world!"); onion_dict_free(a); END_LOCAL(); }
static onion_dict* onion_sessions_redis_get(onion_sessions* sessions, const char *session_id) { onion_session_redis *p = sessions->data; ONION_DEBUG0("Load session %s", session_id); onion_dict *ret = NULL; #ifdef HAVE_PTHREADS pthread_mutex_lock(&p->mutex); #endif // When commands are sent via redisCommand, they are interpolated by the library // so it will avoid any type of command injection. No need to worry about sending // the session_id directly to redis. redisReply* reply = redisCommand(p->context, "HEXISTS SESSIONS %b", session_id, strlen(session_id)); if(reply->type != REDIS_REPLY_INTEGER) { ONION_ERROR("Error getting session_id"); freeReplyObject(reply); goto exit; } else { if(reply->integer == 1) { freeReplyObject(reply); reply = redisCommand(p->context, "HGET SESSIONS %b", session_id, strlen(session_id)); if(reply->type != REDIS_REPLY_STRING) { ONION_ERROR("Error loading session."); freeReplyObject(reply); goto exit; } else { ret = onion_dict_from_json(reply->str); freeReplyObject(reply); goto exit; } } else { ONION_DEBUG0("No session found. Returning NULL"); freeReplyObject(reply); goto exit; } } exit: #ifdef HAVE_PTHREADS pthread_mutex_unlock(&p->mutex); #endif return ret; }
void t18_json_escape_codes(){ INIT_LOCAL(); onion_dict *d=onion_dict_from_json("{ \"hello\": \"Hello\\nworld\", \"second\":\"second\" }"); FAIL_IF_NOT_STRSTR(onion_dict_get(d, "hello"), "Hello\nworld"); FAIL_IF_NOT_STRSTR(onion_dict_get(d, "second"), "second"); onion_dict_free(d); d=onion_dict_from_json("{ \"hello\": \"\\uD83D\\uDE02\" }"); FAIL_IF_NOT_STRSTR(onion_dict_get(d, "hello"), "😂"); onion_dict_free(d); d=onion_dict_from_json("{ \"hello\": \"\\uD83D\\uDE03\" }"); // Another code point FAIL_IF_STRSTR(onion_dict_get(d, "hello"), "😂"); onion_dict_free(d); d=onion_dict_from_json("{ \"hello\": \"\\u007b\" }"); // simple unicode FAIL_IF_NOT_STRSTR(onion_dict_get(d, "hello"), "{"); onion_dict_free(d); d=onion_dict_from_json("{ \"hello\": \"\\\"Quote\" }"); // Escape quote FAIL_IF_NOT_STRSTR(onion_dict_get(d, "hello"), "\"Quote"); onion_dict_free(d); d=onion_dict_from_json("{ \"hello\": \"\"Quote\" }"); // Must fail FAIL_IF_NOT_EQUAL(d, NULL); d=onion_dict_new(); onion_dict_add(d, "hello", "Hello\nWorld\\", 0); onion_dict_add(d, "second", "123", 0); onion_block *b=onion_dict_to_json(d); FAIL_IF_NOT_EQUAL_STR(onion_block_data(b),"{\"hello\":\"Hello\\nWorld\\\\\", \"second\":\"123\"}"); onion_block_free(b); onion_dict_free(d); d=onion_dict_new(); onion_dict_add(d, "hello", "😂\t\n😂", 0); b=onion_dict_to_json(d); FAIL_IF_NOT_EQUAL_STR(onion_block_data(b),"{\"hello\":\"😂\\t\\n😂\"}"); onion_block_free(b); onion_dict_free(d); d=onion_dict_new(); onion_dict_add(d, "hello", "\02\03\x7f", 0); b=onion_dict_to_json(d); FAIL_IF_NOT_EQUAL_STR(onion_block_data(b),"{\"hello\":\"\\u0002\\u0003\\u007F\"}"); onion_block_free(b); onion_dict_free(d); END_LOCAL(); }
static onion_dict* onion_sessions_sqlite3_get(onion_sessions *sessions, const char *session_id){ onion_session_sqlite3 *p=sessions->data; ONION_DEBUG0("Load session %s", session_id); onion_dict *ret=NULL; #ifdef HAVE_PTHREADS pthread_mutex_lock(&p->mutex); #endif sqlite3_reset(p->get); int rc=sqlite3_bind_text(p->get, 1, session_id, -1, SQLITE_STATIC); if( rc!=SQLITE_OK ){ ONION_ERROR("Error binding session_id"); goto exit; } rc=sqlite3_step(p->get); if( rc==SQLITE_DONE ){ ONION_DEBUG0("No session found. Returning NULL"); goto exit; } else if( rc!=SQLITE_ROW ){ ONION_ERROR("Error loading session (%d)", rc); goto exit; } const char * text; text = (const char *)sqlite3_column_text (p->get, 0); ret=onion_dict_from_json(text); if (!ret){ ONION_DEBUG0("Invalid session parsing for id %s: %s", session_id, text); ONION_ERROR("Invalid session data"); } exit: #ifdef HAVE_PTHREADS pthread_mutex_unlock(&p->mutex); #endif return ret; }
/** * @short Convert a JSON string to an onion dictionary. * * This is not full JSON support, only dict side, and with strings. */ static ::Onion::Dict fromJSON(const std::string &jsondata){ return Dict(onion_dict_from_json(jsondata.c_str())); }