/* *------------------------------------------------------------------------- * * mongoc_server_description_new_copy -- * * A copy of a server description that you must destroy, or NULL. * *------------------------------------------------------------------------- */ mongoc_server_description_t * mongoc_server_description_new_copy (const mongoc_server_description_t *description) { mongoc_server_description_t *copy; if (!description) { return NULL; } copy = (mongoc_server_description_t *)bson_malloc0(sizeof (*copy)); copy->id = description->id; memcpy (©->host, &description->host, sizeof (copy->host)); copy->round_trip_time = -1; copy->connection_address = copy->host.host_and_port; /* wait for handle_ismaster to fill these in properly */ copy->has_is_master = false; bson_init_static (©->hosts, kMongocEmptyBson, sizeof (kMongocEmptyBson)); bson_init_static (©->passives, kMongocEmptyBson, sizeof (kMongocEmptyBson)); bson_init_static (©->arbiters, kMongocEmptyBson, sizeof (kMongocEmptyBson)); bson_init_static (©->tags, kMongocEmptyBson, sizeof (kMongocEmptyBson)); bson_init (©->last_is_master); if (description->has_is_master) { mongoc_server_description_handle_ismaster (copy, &description->last_is_master, description->round_trip_time, NULL); } /* Preserve the error */ memcpy (©->error, &description->error, sizeof copy->error); return copy; }
/** * _mongoc_gridfs_file_new_from_bson: * * creates a gridfs file from a bson object * * This is only really useful for instantiating a gridfs file from a server * side object */ mongoc_gridfs_file_t * _mongoc_gridfs_file_new_from_bson (mongoc_gridfs_t *gridfs, const bson_t *data) { mongoc_gridfs_file_t *file; const char *key; bson_iter_t iter; const uint8_t *buf; uint32_t buf_len; ENTRY; BSON_ASSERT (gridfs); BSON_ASSERT (data); file = bson_malloc0 (sizeof *file); file->gridfs = gridfs; bson_copy_to (data, &file->bson); bson_iter_init (&iter, &file->bson); while (bson_iter_next (&iter)) { key = bson_iter_key (&iter); if (0 == strcmp (key, "_id")) { bson_oid_copy (bson_iter_oid (&iter), &file->files_id); } else if (0 == strcmp (key, "length")) { file->length = bson_iter_int64 (&iter); } else if (0 == strcmp (key, "chunkSize")) { file->chunk_size = bson_iter_int32 (&iter); } else if (0 == strcmp (key, "uploadDate")) { file->upload_date = bson_iter_date_time (&iter); } else if (0 == strcmp (key, "md5")) { file->bson_md5 = bson_iter_utf8 (&iter, NULL); } else if (0 == strcmp (key, "filename")) { file->bson_filename = bson_iter_utf8 (&iter, NULL); } else if (0 == strcmp (key, "contentType")) { file->bson_content_type = bson_iter_utf8 (&iter, NULL); } else if (0 == strcmp (key, "aliases")) { bson_iter_array (&iter, &buf_len, &buf); bson_init_static (&file->bson_aliases, buf, buf_len); } else if (0 == strcmp (key, "metadata")) { bson_iter_document (&iter, &buf_len, &buf); bson_init_static (&file->bson_metadata, buf, buf_len); } } /* TODO: is there are a minimal object we should be verifying that we * actually have here? */ RETURN (file); }
bool _mongoc_convert_document (mongoc_client_t *client, const bson_iter_t *iter, bson_t *doc, bson_error_t *error) { uint32_t len; const uint8_t *data; bson_t value; if (!BSON_ITER_HOLDS_DOCUMENT (iter)) { CONVERSION_ERR ("Invalid field \"%s\" in opts, should contain document," " not %s", bson_iter_key (iter), _mongoc_bson_type_to_str (bson_iter_type (iter))); } bson_iter_document (iter, &len, &data); if (!bson_init_static (&value, data, len)) { BSON_ERR ("Corrupt BSON in field \"%s\" in opts", bson_iter_key (iter)); } bson_destroy (doc); bson_copy_to (&value, doc); return true; }
view::const_iterator view::find(stdx::string_view key) const { bson_t b; if (!bson_init_static(&b, _data, _length)) { return cend(); } bson_iter_t iter; // Logically, a default constructed string_view represents the // empty string just as does string_view(""), but they have, // potentially, different represntations, the former having .data // returning nullptr though the latter probably does not. But the // C functions like strncmp below can't be called with nullptr. If // we were called with a string_data such that its .data() member // returns nullptr, then, barring undefined behavior, its length // is known to be zero, and it is equivalent to the empty string, // an instance of which we reset it to. if (key.data() == nullptr) { key = ""; } if (!bson_iter_init_find_w_len(&iter, &b, key.data(), static_cast<int>(key.size()))) { return cend(); } return const_iterator(element( _data, static_cast<uint32_t>(_length), bson_iter_offset(&iter), bson_iter_key_len(&iter))); }
void core::append(const types::b_array& value) { stdx::string_view key = _impl->next_key(); bson_t bson; bson_init_static(&bson, value.value.data(), value.value.length()); bson_append_array(_impl->back(), key.data(), key.length(), &bson); }
static void test_bson_as_json_stack_overflow (void) { uint8_t *buf; bson_t b; size_t buflen = 1024 * 1024 * 17; char *str; int fd; ssize_t r; buf = bson_malloc0(buflen); fd = bson_open(BINARY_DIR"/stackoverflow.bson", O_RDONLY); BSON_ASSERT(-1 != fd); r = bson_read(fd, buf, buflen); BSON_ASSERT(r == 16777220); r = bson_init_static(&b, buf, 16777220); BSON_ASSERT(r); str = bson_as_json(&b, NULL); BSON_ASSERT(str); r = !!strstr(str, "..."); BSON_ASSERT(str); bson_free(str); bson_destroy(&b); bson_free(buf); }
/* {{{ proto WriteError[] WriteResult::getWriteErrors() Returns any write errors that occurred */ PHP_METHOD(WriteResult, getWriteErrors) { bson_iter_t iter, child; php_phongo_writeresult_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_WRITERESULT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } array_init(return_value); if (bson_iter_init_find(&iter, intern->reply, "writeErrors") && BSON_ITER_HOLDS_ARRAY(&iter) && bson_iter_recurse(&iter, &child)) { while (bson_iter_next(&child)) { bson_t cbson; uint32_t len; const uint8_t *data; #if PHP_VERSION_ID >= 70000 zval writeerror; #else zval *writeerror = NULL; #endif if (!BSON_ITER_HOLDS_DOCUMENT(&child)) { continue; } bson_iter_document(&child, &len, &data); if (!bson_init_static(&cbson, data, len)) { continue; } #if PHP_VERSION_ID >= 70000 object_init_ex(&writeerror, php_phongo_writeerror_ce); if (!phongo_writeerror_init(&writeerror, &cbson TSRMLS_CC)) { zval_ptr_dtor(&writeerror); continue; } add_next_index_zval(return_value, &writeerror); #else MAKE_STD_ZVAL(writeerror); object_init_ex(writeerror, php_phongo_writeerror_ce); if (!phongo_writeerror_init(writeerror, &cbson TSRMLS_CC)) { zval_ptr_dtor(&writeerror); continue; } add_next_index_zval(return_value, writeerror); #endif } } }
view::const_iterator view::find(stdx::string_view key) const { bson_t b; bson_iter_t iter; if (!bson_init_static(&b, _data, _length)) { return cend(); } if (!bson_iter_init(&iter, &b)) { return cend(); } if (key.empty()) { return cend(); } while (bson_iter_next(&iter)) { const char* ikey = bson_iter_key(&iter); if (0 == strncmp(key.data(), ikey, key.size())) { return const_iterator(element(iter.raw, iter.len, iter.off)); } } return cend(); }
static void test_bson_corrupt_binary (void) { uint8_t *buf; bson_t b; size_t buflen = 1024; char *str; int fd; ssize_t r; buf = bson_malloc0(buflen); fd = bson_open(BINARY_DIR"/test57.bson", O_RDONLY); BSON_ASSERT(-1 != fd); r = bson_read(fd, buf, buflen); BSON_ASSERT(r == 26); r = bson_init_static(&b, buf, (uint32_t)r); BSON_ASSERT(r); str = bson_as_json(&b, NULL); BSON_ASSERT(!str); bson_destroy(&b); bson_free(buf); }
/** * Performs a count query on a MongoDB collection. * * @param collection The MongoDB collection to query against. * @param query A pointer to a BSON buffer representing the query. * * @return If unsuccessful, returns -1; otherwise, returns the number of * documents counted. */ int64_t monary_query_count(mongoc_collection_t* collection, const uint8_t* query) { bson_error_t error; // A location for BSON errors bson_t query_bson; // The query converted to BSON format int64_t total_count; // The number of documents counted uint32_t query_size; // Length of the query in bytes DEBUG("%s", "Starting Monary count"); // build BSON query data memcpy(&query_size, query, sizeof(uint32_t)); if (!bson_init_static(&query_bson, query, query_size)) { DEBUG("%s", "Failed to initialize raw BSON query"); return -1; } // Make the count query total_count = mongoc_collection_count(collection, MONGOC_QUERY_NONE, &query_bson, 0, 0, NULL, &error); bson_destroy(&query_bson); if (total_count < 0) { DEBUG("error: %d.%d %s", error.domain, error.code, error.message); } return total_count; }
static bool _mongoc_cursor_array_next (mongoc_cursor_t *cursor, const bson_t **bson) { bool ret = true; mongoc_cursor_array_t *arr; ENTRY; arr = (mongoc_cursor_array_t *)cursor->iface_data; *bson = NULL; if (!arr->has_array) { ret = _mongoc_cursor_array_prime(cursor); } if (ret) { ret = bson_iter_next (&arr->iter); } if (ret) { bson_iter_document (&arr->iter, &arr->document_len, &arr->document); bson_init_static (&arr->bson, arr->document, arr->document_len); *bson = &arr->bson; } RETURN (ret); }
void core::append(const types::b_codewscope& value) { stdx::string_view key = _impl->next_key(); bson_t bson; bson_init_static(&bson, value.scope.data(), value.scope.length()); bson_append_code_with_scope(_impl->back(), key.data(), key.length(), value.code.to_string().data(), &bson); }
static void test_bson_init_static (void) { static const bson_uint8_t data[5] = { 5 }; bson_t b; bson_init_static(&b, data, sizeof data); assert((b.flags & BSON_FLAG_RDONLY)); bson_destroy(&b); }
view::iterator view::begin() const { bson_t b; bson_iter_t iter; bson_init_static(&b, _data, _length); bson_iter_init(&iter, &b); bson_iter_next(&iter); return iterator(element{iter.raw, iter.len, iter.off}); }
bool BsonIterSubObject(BSON_ITERATOR *it, BSON *b) { const uint8_t *buffer; uint32_t len; bson_iter_document(it, &len, &buffer); bson_init_static(b, buffer, len); return true; }
/* *-------------------------------------------------------------------------- * * mongoc_server_description_init -- * * Initialize a new server_description_t. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void mongoc_server_description_init (mongoc_server_description_t *sd, const char *address, uint32_t id) { ENTRY; BSON_ASSERT (sd); BSON_ASSERT (address); memset (sd, 0, sizeof *sd); sd->id = id; sd->type = MONGOC_SERVER_UNKNOWN; sd->round_trip_time = -1; sd->set_name = NULL; sd->current_primary = NULL; if (!_mongoc_host_list_from_string(&sd->host, address)) { MONGOC_WARNING("Failed to parse uri for %s", address); return; } sd->connection_address = sd->host.host_and_port; sd->min_wire_version = MONGOC_DEFAULT_WIRE_VERSION; sd->max_wire_version = MONGOC_DEFAULT_WIRE_VERSION; sd->max_msg_size = MONGOC_DEFAULT_MAX_MSG_SIZE; sd->max_bson_obj_size = MONGOC_DEFAULT_BSON_OBJ_SIZE; sd->max_write_batch_size = MONGOC_DEFAULT_WRITE_BATCH_SIZE; bson_init_static (&sd->hosts, kMongocEmptyBson, sizeof (kMongocEmptyBson)); bson_init_static (&sd->passives, kMongocEmptyBson, sizeof (kMongocEmptyBson)); bson_init_static (&sd->arbiters, kMongocEmptyBson, sizeof (kMongocEmptyBson)); bson_init_static (&sd->tags, kMongocEmptyBson, sizeof (kMongocEmptyBson)); bson_init (&sd->last_is_master); EXIT; }
view::const_iterator view::cbegin() const { bson_t b; bson_iter_t iter; bson_init_static(&b, _data, _length); bson_iter_init(&iter, &b); if (!bson_iter_next(&iter)) { return const_iterator{}; } return const_iterator(element{iter.raw, iter.len, iter.off}); }
static const bson_t * _bson_reader_handle_read (bson_reader_handle_t *reader, /* IN */ bool *reached_eof) /* IN */ { int32_t blen; bson_return_val_if_fail (reader, NULL); if (reached_eof) { *reached_eof = false; } while (!reader->done) { if ((reader->end - reader->offset) < 4) { _bson_reader_handle_fill_buffer (reader); continue; } memcpy (&blen, &reader->data[reader->offset], sizeof blen); blen = BSON_UINT32_FROM_LE (blen); if (blen < 5) { return NULL; } if (blen > (int32_t)(reader->end - reader->offset)) { if (blen > (int32_t)reader->len) { _bson_reader_handle_grow_buffer (reader); } _bson_reader_handle_fill_buffer (reader); continue; } if (!bson_init_static (&reader->inline_bson, &reader->data[reader->offset], (uint32_t)blen)) { return NULL; } reader->offset += blen; return &reader->inline_bson; } if (reached_eof) { *reached_eof = reader->done && !reader->failed; } return NULL; }
view::iterator view::find(stdx::string_view key) const { bson_t b; bson_iter_t iter; if (!bson_init_static(&b, _data, _length)) { return end(); } if (bson_iter_init_find(&iter, &b, key.data())) { return iterator(element(iter.raw, iter.len, iter.off)); } else { return end(); } }
/** * Performs an aggregation operation on a MongoDB collection. * * @param collection The MongoDB collection to query against. * @param pipeline A pointer to a BSON buffer representing the pipeline. * @param coldata The column data to store the results in. * * @return If successful, a Monary cursor that should be freed with * monary_close_query() when no longer in use. If unsuccessful, or if an invalid * pipeline was passed in, NULL is returned. */ monary_cursor* monary_init_aggregate(mongoc_collection_t* collection, const uint8_t* pipeline, monary_column_data* coldata) { bson_t pl_bson; int32_t pl_size; mongoc_cursor_t* mcursor; monary_cursor* cursor; // Sanity checks if (!collection) { DEBUG("%s", "Invalid collection"); return NULL; } else if (!pipeline) { DEBUG("%s", "Invalid pipeline"); return NULL; } // Build BSON pipeline memcpy(&pl_size, pipeline, sizeof(int32_t)); pl_size = (int32_t) BSON_UINT32_FROM_LE(pl_size); if (!bson_init_static(&pl_bson, pipeline, pl_size)) { DEBUG("%s", "Failed to initialize raw BSON pipeline"); return NULL; } // Get an aggregation cursor mcursor = mongoc_collection_aggregate(collection, MONGOC_QUERY_NONE, &pl_bson, NULL, NULL); // Clean up bson_destroy(&pl_bson); if (!mcursor) { DEBUG("%s", "An error occurred with the aggregation"); return NULL; } cursor = (monary_cursor*) malloc(sizeof(monary_cursor)); cursor->mcursor = mcursor; cursor->coldata = coldata; return cursor; }
void bsonToMongoCodeWithScope(bson_iter_t* iter, Array* output) { uint32_t length; uint32_t scope_len; const uint8_t* scope; const char* code = bson_iter_codewscope(iter, &length, &scope_len, &scope); bson_t bson; bson_init_static(&bson, scope, scope_len); Array scopeArray = Array::Create(); bsonToVariant(&bson, &scopeArray); bsonToObject(iter, output, &s_MongoCode, make_packed_array(String(code, length, CopyString), scopeArray) ); }
void core::concatenate(const bsoncxx::document::view& view) { bson_t other; bson_init_static(&other, view.data(), view.length()); if (_impl->is_array()) { bson_iter_t iter; bson_iter_init(&iter, &other); while (bson_iter_next(&iter)) { stdx::string_view key = _impl->next_key(); bson_append_iter(_impl->back(), key.data(), key.length(), &iter); } } else { bson_concat(_impl->back(), &other); } }
bool _mongoc_rpc_reply_get_first (mongoc_rpc_reply_t *reply, bson_t *bson) { int32_t len; if (!reply->documents || reply->documents_len < 4) { return false; } memcpy(&len, reply->documents, 4); len = BSON_UINT32_FROM_LE(len); if (reply->documents_len < len) { return false; } return bson_init_static(bson, reply->documents, len); }
static void append_documents_from_cmd (const mongoc_cmd_t *cmd, mongoc_apm_command_started_t *event) { int32_t doc_len; bson_t doc; const uint8_t *pos; const char *field_name; bson_t bson; char str[16]; const char *key; uint32_t i; if (!cmd->payload || !cmd->payload_size) { return; } if (!event->command_owned) { event->command = bson_copy (event->command); event->command_owned = true; } /* make array from outgoing OP_MSG payload type 1 on an "insert", * "update", or "delete" command. */ field_name = _mongoc_get_documents_field_name (cmd->command_name); BSON_ASSERT (field_name); BSON_ASSERT (BSON_APPEND_ARRAY_BEGIN (event->command, field_name, &bson)); pos = cmd->payload; i = 0; while (pos < cmd->payload + cmd->payload_size) { memcpy (&doc_len, pos, sizeof (doc_len)); doc_len = BSON_UINT32_FROM_LE (doc_len); BSON_ASSERT (bson_init_static (&doc, pos, (size_t) doc_len)); bson_uint32_to_string (i, &key, str, sizeof (str)); BSON_APPEND_DOCUMENT (&bson, key, &doc); pos += doc_len; i++; } bson_append_array_end (event->command, &bson); }
static const bson_t * _bson_reader_data_read (bson_reader_data_t *reader, bson_bool_t *reached_eof) { bson_uint32_t blen; bson_return_val_if_fail (reader, NULL); if (reached_eof) { *reached_eof = FALSE; } if ((reader->offset + 4) < reader->length) { memcpy (&blen, &reader->data[reader->offset], sizeof blen); blen = BSON_UINT32_FROM_LE (blen); if ((blen + reader->offset) <= reader->length) { if (!bson_init_static (&reader->inline_bson, &reader->data[reader->offset], blen)) { if (reached_eof) { *reached_eof = FALSE; } return NULL; } reader->offset += blen; if (reached_eof) { *reached_eof = (reader->offset == reader->length); } return &reader->inline_bson; } } if (reached_eof) { *reached_eof = (reader->offset == reader->length); } return NULL; }
static const bson_t * _bson_reader_fd_read (bson_reader_fd_t *reader, bson_bool_t *reached_eof) { bson_uint32_t blen; bson_return_val_if_fail (reader, NULL); while (!reader->done) { if ((reader->end - reader->offset) < 4) { _bson_reader_fd_fill_buffer (reader); continue; } memcpy (&blen, &reader->data[reader->offset], sizeof blen); blen = BSON_UINT32_FROM_LE (blen); if (blen > (reader->end - reader->offset)) { if (blen > reader->len) { _bson_reader_fd_grow_buffer (reader); } _bson_reader_fd_fill_buffer (reader); continue; } if (!bson_init_static (&reader->inline_bson, &reader->data[reader->offset], blen)) { return NULL; } reader->offset += blen; return &reader->inline_bson; } if (reached_eof) { *reached_eof = reader->done && !reader->failed; } return NULL; }
void bsonToArray(bson_iter_t* iter, Array* output, bool isDocument) { bson_t bson; const uint8_t *document = NULL; uint32_t document_len = 0; if (isDocument) { bson_iter_document(iter, &document_len, &document); } else { bson_iter_array(iter, &document_len, &document); } bson_init_static(&bson, document, document_len); Array child = Array::Create(); bsonToVariant(&bson, &child); output->add( String(bson_iter_key(iter)), child ); }
bson_bool_t _mongoc_rpc_reply_get_first (mongoc_rpc_reply_t *reply, bson_t *bson) { bson_int32_t len; bson_return_val_if_fail(reply, FALSE); bson_return_val_if_fail(bson, FALSE); if (!reply->documents || reply->documents_len < 4) { return FALSE; } memcpy(&len, reply->documents, 4); len = BSON_UINT32_FROM_LE(len); if (reply->documents_len < len) { return FALSE; } return bson_init_static(bson, reply->documents, len); }
static const bson_t * _bson_reader_data_read (bson_reader_data_t *reader, /* IN */ bool *reached_eof) /* IN */ { int32_t blen; bson_return_val_if_fail (reader, NULL); if (reached_eof) { *reached_eof = false; } if ((reader->offset + 4) < reader->length) { memcpy (&blen, &reader->data[reader->offset], sizeof blen); blen = BSON_UINT32_FROM_LE (blen); if (blen < 5) { return NULL; } if (blen > (int32_t)(reader->length - reader->offset)) { return NULL; } if (!bson_init_static (&reader->inline_bson, &reader->data[reader->offset], (uint32_t)blen)) { return NULL; } reader->offset += blen; return &reader->inline_bson; } if (reached_eof) { *reached_eof = (reader->offset == reader->length); } return NULL; }
static request_t * _check_op_query (mock_server_t *server, test_collection_find_with_opts_t *test_data) { mongoc_query_flags_t flags; request_t *request; const bson_t *doc; bson_iter_t iter; uint32_t len; const uint8_t *data; bson_t query; /* Server Selection Spec: all queries to standalone set slaveOk. */ flags = test_data->expected_flags | MONGOC_QUERY_SLAVE_OK; request = mock_server_receives_query ( server, "db.collection", flags, test_data->expected_skip, test_data->expected_n_return, test_data->expected_op_query, test_data->expected_op_query_projection); ASSERT (request); /* check that nothing unexpected is in $query */ if (bson_empty (test_data->filter_bson)) { doc = request_get_doc (request, 0); if (bson_iter_init_find (&iter, doc, "$query")) { ASSERT (BSON_ITER_HOLDS_DOCUMENT (&iter)); bson_iter_document (&iter, &len, &data); bson_init_static (&query, data, (size_t) len); ASSERT (bson_empty (&query)); } } return request; }