@@ -59,6 +59,8 @@ namespace Setting
5959 extern const SettingsBool mongodb_throw_on_unsupported_query;
6060}
6161
62+ static constexpr const char * MONGODB_RESERVED_CHARS = " !?#/'\" ,;:$&()[]*+=@" ;
63+
6264void MongoDBConfiguration::checkHosts (const ContextPtr & context) const
6365{
6466 // Because domain records will be resolved inside the driver, we can't check resolved IPs for our restrictions.
@@ -108,6 +110,13 @@ Pipe StorageMongoDB::read(
108110 std::move (options), std::make_shared<const Block>(std::move (sample_block)), max_block_size));
109111}
110112
113+ static String encodeString (const String & str)
114+ {
115+ String encoded;
116+ Poco::URI::encode (str, MONGODB_RESERVED_CHARS, encoded);
117+ return encoded;
118+ }
119+
111120static MongoDBConfiguration getConfigurationImpl (const StorageID * table_id, ASTs engine_args, ContextPtr context, bool allow_excessive_path_in_host)
112121{
113122 MongoDBConfiguration configuration;
@@ -124,10 +133,12 @@ static MongoDBConfiguration getConfigurationImpl(const StorageID * table_id, AST
124133 " host" , " port" , " user" , " password" , " database" , " collection" }, {" options" , " oid_columns" });
125134 String user = named_collection->get <String>(" user" );
126135 String auth_string;
127- String escaped_password;
128- Poco::URI::encode (named_collection->get <String>(" password" ), " !?#/'\" ,;:$&()[]*+=@" , escaped_password);
129136 if (!user.empty ())
130- auth_string = fmt::format (" {}:{}@" , user, escaped_password);
137+ {
138+ String escaped_user = encodeString (user);
139+ String escaped_password = encodeString (named_collection->get <String>(" password" ));
140+ auth_string = fmt::format (" {}:{}@" , escaped_user, escaped_password);
141+ }
131142 configuration.uri = std::make_unique<mongocxx::uri>(fmt::format (" mongodb://{}{}:{}/{}?{}" ,
132143 auth_string,
133144 named_collection->get <String>(" host" ),
@@ -154,10 +165,12 @@ static MongoDBConfiguration getConfigurationImpl(const StorageID * table_id, AST
154165
155166 String user = checkAndGetLiteralArgument<String>(engine_args[3 ], " user" );
156167 String auth_string;
157- String escaped_password;
158- Poco::URI::encode (checkAndGetLiteralArgument<String>(engine_args[4 ], " password" ), " !?#/'\" ,;:$&()[]*+=@" , escaped_password);
159168 if (!user.empty ())
160- auth_string = fmt::format (" {}:{}@" , user, escaped_password);
169+ {
170+ String escaped_user = encodeString (user);
171+ String escaped_password = encodeString (checkAndGetLiteralArgument<String>(engine_args[4 ], " password" ));
172+ auth_string = fmt::format (" {}:{}@" , escaped_user, escaped_password);
173+ }
161174
162175 auto host_port = checkAndGetLiteralArgument<String>(engine_args[0 ], " host:port" );
163176 auto database_name = checkAndGetLiteralArgument<String>(engine_args[1 ], " database" );
0 commit comments