SEXP R_raw_to_bson(SEXP buf){ bson_error_t err; bson_t *b = bson_new_from_data(RAW(buf), length(buf)); if(!b) stop(err.message); return bson2r(b); }
static void do_inserts (mongo_sync_connection *conn) { bson *base; gint i; base = bson_build (BSON_TYPE_STRING, "tutorial-program", "tut_hl_client.c", -1, BSON_TYPE_INT32, "the answer to life, the universe and everything", 42, BSON_TYPE_NONE); bson_finish (base); for (i = 0; i < 1000; i++) { bson *n; n = bson_new_from_data (bson_data (base), bson_size (base) - 1); bson_append_int32 (n, "counter", i); bson_finish (n); if (!mongo_sync_cmd_insert (conn, "lmc.tutorial", n, NULL)) { fprintf (stderr, "Error inserting document %d: %s\n", i, strerror (errno)); exit (1); } bson_free (n); } bson_free (base); }
void test_mongo_wire_cmd_custom (void) { bson *cmd; mongo_packet *p; mongo_packet_header hdr; const guint8 *data; gint32 data_size; bson_cursor *c; gint32 pos; cmd = bson_new (); bson_append_int32 (cmd, "getnonce", 1); ok (mongo_wire_cmd_custom (1, "test", 0, NULL) == NULL, "mongo_wire_cmd_custom() fails with a NULL command"); ok (mongo_wire_cmd_custom (1, "test", 0, cmd) == NULL, "mongo_wire_cmd_custom() fails with an unfinished command"); bson_finish (cmd); ok (mongo_wire_cmd_custom (1, NULL, 0, cmd) == NULL, "mongo_wire_cmd_custom() fails with a NULL db"); ok ((p = mongo_wire_cmd_custom (1, "test", 0, cmd)) != NULL, "mongo_wire_cmd_custom() works"); bson_free (cmd); /* Verify the header */ mongo_wire_packet_get_header (p, &hdr); cmp_ok ((data_size = mongo_wire_packet_get_data (p, &data)), "!=", -1, "Packet data size looks fine"); cmp_ok (hdr.length, "==", sizeof (mongo_packet_header) + data_size, "Packet header length is OK"); cmp_ok (hdr.id, "==", 1, "Packet request ID is ok"); cmp_ok (hdr.resp_to, "==", 0, "Packet reply ID is ok"); /* * Test the created request */ /* pos = zero + collection_name + NULL + skip + ret */ pos = sizeof (gint32) + strlen ("test.$cmd") + 1 + sizeof (gint32) * 2; ok ((cmd = bson_new_from_data (data + pos, _DOC_SIZE (data, pos) - 1)) != NULL, "Packet contains a BSON document"); bson_finish (cmd); ok ((c = bson_find (cmd, "getnonce")) != NULL, "BSON object contains a 'getnonce' key"); cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_INT32, "'getnonce' key has the correct type"); ok (bson_cursor_next (c) == FALSE, "'getnonce' key is the last in the object"); bson_cursor_free (c); bson_free (cmd); mongo_wire_packet_free (p); }
void mongoc_apm_command_started_init (mongoc_apm_command_started_t *event, const bson_t *command, const char *database_name, const char *command_name, int64_t request_id, int64_t operation_id, const mongoc_host_list_t *host, uint32_t server_id, void *context) { bson_iter_t iter; uint32_t len; const uint8_t *data; /* Command Monitoring Spec: * * In cases where queries or commands are embedded in a $query parameter * when a read preference is provided, they MUST be unwrapped and the value * of the $query attribute becomes the filter or the command in the started * event. The read preference will subsequently be dropped as it is * considered metadata and metadata is not currently provided in the command * events. */ if (bson_has_field (command, "$readPreference")) { if (bson_iter_init_find (&iter, command, "$query") && BSON_ITER_HOLDS_DOCUMENT (&iter)) { bson_iter_document (&iter, &len, &data); event->command = bson_new_from_data (data, len); event->command_owned = true; } else { /* Got $readPreference without $query, probably OP_MSG */ event->command = (bson_t *) command; event->command_owned = false; } } else { /* discard "const", we promise not to modify "command" */ event->command = (bson_t *) command; event->command_owned = false; } event->database_name = database_name; event->command_name = command_name; event->request_id = request_id; event->operation_id = operation_id; event->host = host; event->server_id = server_id; event->context = context; }
ERL_NIF_TERM decode(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { cabala_st *st = (cabala_st*)enif_priv_data(env); ERL_NIF_TERM data, opts, out; decode_state ds; ErlNifBinary bin; bson_t *bson; /* init params */ if(argc != 2) { return enif_make_badarg(env); } init_state(&ds, env, st); data = argv[0]; opts = argv[1]; /* parse decode options */ while(enif_get_list_cell(env, opts, &out, &opts)) { if(enif_compare(out, st->atom_return_maps) == 0) { ds.return_maps = 1; } else { return enif_make_badarg(env); } } /* check data is bson */ if(!enif_inspect_binary(env, data, &bin)) { return enif_make_badarg(env); } bson = bson_new_from_data(bin.data, bin.size); if(!bson) { return make_error(st, env, "badbson"); } if(bson_empty(bson)) { bson_destroy(bson); return make_empty_document(env, ds.return_maps); } LOG("decode begin, return_maps: %d\r\n", ds.return_maps); if(!iter_bson(bson, &out, &ds)) { out = make_error(st, env, "internal_error"); } bson_destroy(bson); return out; }
void perl_mongo_sv_to_bson (bson_t * bson, SV *sv, HV *opts) { if (!SvROK (sv)) { croak ("not a reference"); } if ( ! sv_isobject(sv) ) { switch ( SvTYPE(SvRV(sv)) ) { case SVt_PVHV: hvdoc_to_bson (bson, sv, opts, EMPTY_STACK); break; case SVt_PVAV: avdoc_to_bson(bson, sv, opts, EMPTY_STACK); break; default: sv_dump(sv); croak ("type unhandled"); } } else { SV *obj; char *class; obj = SvRV(sv); class = HvNAME(SvSTASH(obj)); if ( strEQ(class, "Tie::IxHash") ) { ixhashdoc_to_bson(bson, sv, opts, EMPTY_STACK); } else if ( strEQ(class, "MongoDB::BSON::_EncodedDoc") ) { STRLEN str_len; SV **svp; SV *encoded; const char *bson_str; bson_t *child; encoded = _hv_fetchs_sv((HV *)obj, "bson"); bson_str = SvPV(encoded, str_len); child = bson_new_from_data((uint8_t*) bson_str, str_len); bson_concat(bson, child); bson_destroy(child); } else if (SvTYPE(obj) == SVt_PVHV) {
static void test_bson_alloc (void) { static const bson_uint8_t empty_bson[] = { 5, 0, 0, 0, 0 }; bson_t *b; b = bson_new(); assert_cmpint(b->len, ==, 5); assert((b->flags & BSON_FLAG_INLINE)); assert(!(b->flags & BSON_FLAG_CHILD)); assert(!(b->flags & BSON_FLAG_STATIC)); assert(!(b->flags & BSON_FLAG_NO_FREE)); bson_destroy(b); /* * This checks that we fit in the inline buffer size. */ b = bson_sized_new(44); assert_cmpint(b->len, ==, 5); assert((b->flags & BSON_FLAG_INLINE)); bson_destroy(b); /* * Make sure we grow to next power of 2. */ b = bson_sized_new(121); assert_cmpint(b->len, ==, 5); assert(!(b->flags & BSON_FLAG_INLINE)); bson_destroy(b); /* * Make sure we grow to next power of 2. */ b = bson_sized_new(129); assert_cmpint(b->len, ==, 5); assert(!(b->flags & BSON_FLAG_INLINE)); bson_destroy(b); b = bson_new_from_data(empty_bson, sizeof empty_bson); assert_cmpint(b->len, ==, sizeof empty_bson); assert((b->flags & BSON_FLAG_INLINE)); assert(!memcmp(bson_get_data(b), empty_bson, sizeof empty_bson)); bson_destroy(b); }
static bson_t * get_bson (const char *filename) { uint8_t buf[4096]; bson_t *b; ssize_t len; int fd; if (-1 == (fd = bson_open(filename, O_RDONLY))) { fprintf(stderr, "Failed to open: %s\n", filename); abort(); } if ((len = bson_read(fd, buf, sizeof buf)) < 0) { fprintf(stderr, "Failed to read: %s\n", filename); abort(); } assert(len > 0); b = bson_new_from_data(buf, (uint32_t)len); bson_close(fd); return b; }
static bson_t * get_bson (const char *filename) { bson_uint32_t len; bson_uint8_t buf[4096]; bson_t *b; char real_filename[256]; int fd; snprintf(real_filename, sizeof real_filename, "tests/binary/%s", filename); real_filename[sizeof real_filename - 1] = '\0'; if (-1 == (fd = open(real_filename, O_RDONLY))) { fprintf(stderr, "Failed to open: %s\n", real_filename); abort(); } len = read(fd, buf, sizeof buf); b = bson_new_from_data(buf, len); close(fd); return b; }
void test_mongo_wire_cmd_insert_n (void) { bson *ins, *tmp; const bson *docs[10]; mongo_packet *p; mongo_packet_header hdr; const guint8 *data; gint32 data_size; bson_cursor *c; gint32 pos; ins = test_bson_generate_full (); tmp = bson_new (); docs[0] = ins; docs[1] = tmp; docs[2] = ins; docs[3] = ins; docs[4] = NULL; docs[5] = ins; ok (mongo_wire_cmd_insert_n (1, NULL, 1, docs) == NULL, "mongo_wire_cmd_insert_n() fails with a NULL namespace"); ok (mongo_wire_cmd_insert_n (1, "test.ns", 1, NULL) == NULL, "mongo_wire_cmd_insert_n() fails with no documents"); ok (mongo_wire_cmd_insert_n (1, "test.ns", 0, docs) == NULL, "mongo_wire_cmd_insert_n() fails with no documents"); ok (mongo_wire_cmd_insert_n (1, "test.ns", 2, docs) == NULL, "mongo_wire_cmd_insert_n() fails with an unfinished document"); bson_finish (tmp); ok (mongo_wire_cmd_insert_n (1, "test.ns", 5, docs) == NULL, "mongo_wire_cmd_insert_n() fails with a NULL document in the array"); ok ((p = mongo_wire_cmd_insert_n (1, "test.ns", 3, docs)) != NULL, "mongo_wire_cmd_insert() works"); bson_free (ins); bson_free (tmp); /* Test basic header data */ mongo_wire_packet_get_header (p, &hdr); cmp_ok ((data_size = mongo_wire_packet_get_data (p, &data)), "!=", -1, "Packet data size appears fine"); cmp_ok (hdr.length, "==", sizeof (mongo_packet_header) + data_size, "Packet header length is correct"); cmp_ok (hdr.id, "==", 1, "Header ID is ok"); cmp_ok (hdr.resp_to, "==", 0, "Response ID is ok"); /* * Test the first document */ /* pos = zero + collection_name + NULL */ pos = sizeof (gint32) + strlen ("test.ns") + 1; ok ((ins = bson_new_from_data (data + pos, _DOC_SIZE (data, pos) - 1)) != NULL, "First document is included"); bson_finish (ins); ok ((c = bson_find (ins, "int32")) != NULL, "BSON contains 'int32'"); cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_INT32, "int32 has correct type"); bson_cursor_next (c); cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_INT64, "next element has correct type too"); ok (bson_cursor_next (c) == FALSE, "No more data after the update BSON object"); bson_cursor_free (c); /* * Test the second document */ pos += bson_size (ins); ok ((tmp = bson_new_from_data (data + pos, _DOC_SIZE (data, pos) - 1)) != NULL, "Second document is included"); bson_finish (tmp); cmp_ok (bson_size (tmp), "==", 5, "Second document is empty"); bson_free (ins); bson_free (tmp); mongo_wire_packet_free (p); }
void test_mongo_wire_cmd_update (void) { bson *sel, *upd, *tmp; mongo_packet *p; mongo_packet_header hdr; const guint8 *data; gint32 data_size; bson_cursor *c; gint32 pos; sel = bson_new (); bson_append_null (sel, "_id"); bson_finish (sel); upd = test_bson_generate_full (); ok (mongo_wire_cmd_update (1, NULL, 0, sel, upd) == NULL, "mongo_wire_cmd_update() with a NULL namespace should fail"); ok (mongo_wire_cmd_update (1, "test.ns", 0, NULL, upd) == NULL, "mongo_wire_cmd_update() with a NULL selector should fail"); ok (mongo_wire_cmd_update (1, "test.ns", 0, sel, NULL) == NULL, "mongo_wire_cmd_update() with a NULL update should fail"); tmp = bson_new (); ok (mongo_wire_cmd_update (1, "test.ns", 0, tmp, upd) == NULL, "mongo_wire_cmd_update() fails with an unfinished selector"); ok (mongo_wire_cmd_update (1, "test.ns", 0, sel, tmp) == NULL, "mongo_wire_cmd_update() fails with an unfinished update"); bson_free (tmp); ok ((p = mongo_wire_cmd_update (1, "test.ns", 0, sel, upd)) != NULL, "mongo_wire_cmd_update() works"); bson_free (sel); mongo_wire_packet_get_header (p, &hdr); cmp_ok ((data_size = mongo_wire_packet_get_data (p, &data)), "!=", -1, "Packet data size looks fine"); cmp_ok (hdr.length, "==", sizeof (mongo_packet_header) + data_size, "Packet header length is OK"); cmp_ok (hdr.id, "==", 1, "Packet request ID is ok"); cmp_ok (hdr.resp_to, "==", 0, "Packet reply ID is ok"); /* * Verify the selector object. */ /* pos = zero + collection_name + NULL + flags */ pos = sizeof (gint32) + strlen ("test.ns") + 1 + sizeof (gint32); ok ((sel = bson_new_from_data (data + pos, (gint32)data[pos] - 1)) != NULL, "Packet contains a valid BSON selector document"); bson_finish (sel); ok ((c = bson_find (sel, "_id")) != NULL, "BSON contains an _id"); cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_NULL, "_id has correct type"); bson_cursor_free (c); bson_free (sel); /* * Verify the update object */ pos += (gint32)data[pos]; ok ((tmp = bson_new_from_data (data + pos, bson_stream_doc_size (data, pos) - 1)) != NULL, "Packet contains a valid BSON update document"); bson_finish (tmp); cmp_ok (bson_size (upd), "==", bson_size (tmp), "Packet's update document has the correct size"); ok ((c = bson_find (tmp, "int32")) != NULL, "BSON contains 'int32'"); cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_INT32, "int32 has correct type"); bson_cursor_next (c); cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_INT64, "next element has correct type too"); ok (bson_cursor_next (c) == FALSE, "No more data after the update BSON object"); bson_cursor_free (c); bson_free (tmp); bson_free (upd); mongo_wire_packet_free (p); }
void test_mongo_wire_cmd_delete (void) { mongo_packet *p; bson *s, *tmp; mongo_packet_header hdr; const guint8 *data; gint32 data_size; gint32 pos; bson_cursor *c; s = test_bson_generate_full (); tmp = bson_new (); ok (mongo_wire_cmd_delete (1, NULL, 0, s) == NULL, "mongo_wire_cmd_delete() fails with a NULL namespace"); ok (mongo_wire_cmd_delete (1, "test.ns", 0, NULL) == NULL, "mongo_wire_cmd_delete() fails with a NULL selector"); ok (mongo_wire_cmd_delete (1, "test.ns", 0, tmp) == NULL, "mongo_wire_cmd_delete() fails with an unfinished selector"); bson_free (tmp); ok ((p = mongo_wire_cmd_delete (1, "test.ns", 0, s)) != NULL, "mongo_wire_cmd_delete() works"); bson_free (s); /* Test basic header data */ mongo_wire_packet_get_header (p, &hdr); cmp_ok ((data_size = mongo_wire_packet_get_data (p, &data)), "!=", -1, "Packet data size appears fine"); cmp_ok (hdr.length, "==", sizeof (mongo_packet_header) + data_size, "Packet header length is correct"); cmp_ok (hdr.id, "==", 1, "Header ID is ok"); cmp_ok (hdr.resp_to, "==", 0, "Response ID is ok"); /* * Test the constructed request */ /* pos = zero + ns + NULL + flags */ pos = sizeof (gint32) + strlen ("test.ns") + 1 + sizeof (gint32); ok ((s = bson_new_from_data (data + pos, _DOC_SIZE (data, pos) - 1)) != NULL, "Packet contains a valid BSON update document"); bson_finish (s); ok ((c = bson_find (s, "int32")) != NULL, "BSON contains 'int32'"); cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_INT32, "int32 has correct type"); bson_cursor_next (c); cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_INT64, "next element has correct type too"); ok (bson_cursor_next (c) == FALSE, "No more data after the update BSON object"); bson_cursor_free (c); bson_free (s); mongo_wire_packet_free (p); }
static void test_bson_iter_fuzz (void) { uint8_t *data; uint32_t len = 512; uint32_t len_le; uint32_t r; bson_iter_t iter; bson_t *b; uint32_t i; int pass; len_le = BSON_UINT32_TO_LE(len); for (pass = 0; pass < FUZZ_N_PASSES; pass++) { data = bson_malloc0(len); memcpy(data, &len_le, sizeof (len_le)); for (i = 4; i < len; i += 4) { r = rand(); memcpy(&data[i], &r, sizeof (r)); } if (!(b = bson_new_from_data(data, len))) { /* * It could fail on buffer length or missing trailing null byte. */ bson_free (data); continue; } BSON_ASSERT(b); /* * TODO: Most of the following ignores the key. That should be fixed * but has it's own perils too. */ assert(bson_iter_init(&iter, b)); while (bson_iter_next(&iter)) { assert(iter.next_off < len); switch (bson_iter_type(&iter)) { case BSON_TYPE_ARRAY: case BSON_TYPE_DOCUMENT: { const uint8_t *child = NULL; uint32_t child_len = 0; bson_iter_document(&iter, &child_len, &child); if (child_len) { assert(child); assert(child_len >= 5); assert((iter.off + child_len) < b->len); assert(child_len < (uint32_t) -1); memcpy(&child_len, child, sizeof (child_len)); child_len = BSON_UINT32_FROM_LE(child_len); assert(child_len >= 5); } } break; case BSON_TYPE_DOUBLE: case BSON_TYPE_UTF8: case BSON_TYPE_BINARY: case BSON_TYPE_UNDEFINED: break; case BSON_TYPE_OID: assert(iter.off + 12 < iter.len); break; case BSON_TYPE_BOOL: case BSON_TYPE_DATE_TIME: case BSON_TYPE_NULL: case BSON_TYPE_REGEX: /* TODO: check for 2 valid cstring. */ case BSON_TYPE_DBPOINTER: case BSON_TYPE_CODE: case BSON_TYPE_SYMBOL: case BSON_TYPE_CODEWSCOPE: case BSON_TYPE_INT32: case BSON_TYPE_TIMESTAMP: case BSON_TYPE_INT64: case BSON_TYPE_DECIMAL128: case BSON_TYPE_MAXKEY: case BSON_TYPE_MINKEY: break; case BSON_TYPE_EOD: default: /* Code should not be reached. */ assert(false); break; } } bson_destroy(b); bson_free(data); } }