Unification

This commit is contained in:
kssenii 2021-07-14 13:13:37 +00:00
parent b393603b57
commit d62cbbb8a5
7 changed files with 86 additions and 57 deletions

View File

@ -130,28 +130,6 @@ bool pathStartsWith(const String & path, const String & prefix_path)
return pathStartsWith(filesystem_path, filesystem_prefix_path);
}
String SQLiteDatabaseValidatePath(const String & path, const String & user_files_path)
{
String canonical_user_files_path = fs::canonical(user_files_path);
String canonical_path;
std::error_code err;
if (fs::path(path).is_relative())
canonical_path = fs::canonical(fs::path(user_files_path) / path, err);
else
canonical_path = fs::canonical(path, err);
if (err)
throw Exception(ErrorCodes::PATH_ACCESS_DENIED, "SQLite database path '{}' is invalid. Error: {}", path, err.message());
if (!canonical_path.starts_with(canonical_user_files_path))
throw Exception(ErrorCodes::PATH_ACCESS_DENIED,
"SQLite database file path '{}' must be inside 'user_files' directory", path);
return canonical_path;
}
}

View File

@ -35,7 +35,6 @@ bool pathStartsWith(const std::filesystem::path & path, const std::filesystem::p
/// Returns true if path starts with prefix path
bool pathStartsWith(const String & path, const String & prefix_path);
String SQLiteDatabaseValidatePath(const String & path, const String & user_files_path);
}
namespace FS

View File

@ -10,7 +10,7 @@
#include <Parsers/ASTColumnDeclaration.h>
#include <Interpreters/Context.h>
#include <Storages/StorageSQLite.h>
#include <Common/filesystemHelpers.h>
#include <Databases/SQLite/SQLiteUtils.h>
namespace DB
@ -20,7 +20,6 @@ namespace ErrorCodes
{
extern const int SQLITE_ENGINE_ERROR;
extern const int UNKNOWN_TABLE;
extern const int PATH_ACCESS_DENIED;
}
DatabaseSQLite::DatabaseSQLite(
@ -32,17 +31,7 @@ DatabaseSQLite::DatabaseSQLite(
, database_engine_define(database_engine_define_->clone())
, log(&Poco::Logger::get("DatabaseSQLite"))
{
auto db_path = SQLiteDatabaseValidatePath(database_path_, context_->getUserFilesPath());
sqlite3 * tmp_sqlite_db = nullptr;
int status = sqlite3_open(db_path.c_str(), &tmp_sqlite_db);
if (status != SQLITE_OK)
throw Exception(ErrorCodes::PATH_ACCESS_DENIED,
"Cannot access sqlite database. Error status: {}. Message: {}",
status, sqlite3_errstr(status));
sqlite_db = std::shared_ptr<sqlite3>(tmp_sqlite_db, sqlite3_close);
sqlite_db = openSQLiteDB(database_path_, context_);
}

View File

@ -0,0 +1,57 @@
#include "SQLiteUtils.h"
#if USE_SQLITE
#include <filesystem>
namespace fs = std::filesystem;
namespace DB
{
namespace ErrorCodes
{
extern const int PATH_ACCESS_DENIED;
}
String SQLiteDatabaseValidatePath(const String & path, const String & user_files_path)
{
String canonical_user_files_path = fs::canonical(user_files_path);
String canonical_path;
std::error_code err;
if (fs::path(path).is_relative())
canonical_path = fs::canonical(fs::path(user_files_path) / path, err);
else
canonical_path = fs::canonical(path, err);
if (err)
throw Exception(ErrorCodes::PATH_ACCESS_DENIED, "SQLite database path '{}' is invalid. Error: {}", path, err.message());
if (!canonical_path.starts_with(canonical_user_files_path))
throw Exception(ErrorCodes::PATH_ACCESS_DENIED,
"SQLite database file path '{}' must be inside 'user_files' directory", path);
return canonical_path;
}
SQLitePtr openSQLiteDB(const String & database_path, ContextPtr context)
{
auto validated_path = SQLiteDatabaseValidatePath(database_path, context->getUserFilesPath());
sqlite3 * tmp_sqlite_db = nullptr;
int status = sqlite3_open(validated_path.c_str(), &tmp_sqlite_db);
if (status != SQLITE_OK)
throw Exception(ErrorCodes::PATH_ACCESS_DENIED,
"Cannot access sqlite database. Error status: {}. Message: {}",
status, sqlite3_errstr(status));
return std::shared_ptr<sqlite3>(tmp_sqlite_db, sqlite3_close);
}
}
#endif

View File

@ -0,0 +1,22 @@
#pragma once
#if !defined(ARCADIA_BUILD)
#include "config_core.h"
#endif
#if USE_SQLITE
#include <Core/Types.h>
#include <Interpreters/Context.h>
#include <sqlite3.h>
namespace DB
{
using SQLitePtr = std::shared_ptr<sqlite3>;
SQLitePtr openSQLiteDB(const String & database_path, ContextPtr context);
}
#endif

View File

@ -3,6 +3,7 @@
#if USE_SQLITE
#include <common/range.h>
#include <DataStreams/SQLiteBlockInputStream.h>
#include <Databases/SQLite/SQLiteUtils.h>
#include <DataTypes/DataTypeString.h>
#include <Interpreters/Context.h>
#include <Formats/FormatFactory.h>
@ -23,7 +24,6 @@ namespace ErrorCodes
{
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
extern const int SQLITE_ENGINE_ERROR;
extern const int PATH_ACCESS_DENIED;
}
StorageSQLite::StorageSQLite(
@ -159,16 +159,9 @@ void registerStorageSQLite(StorageFactory & factory)
const auto database_path = engine_args[0]->as<ASTLiteral &>().value.safeGet<String>();
const auto table_name = engine_args[1]->as<ASTLiteral &>().value.safeGet<String>();
auto db_path = SQLiteDatabaseValidatePath(database_path, args.getContext()->getUserFilesPath());
auto sqlite_db = openSQLiteDB(database_path, args.getContext());
sqlite3 * tmp_sqlite_db = nullptr;
int status = sqlite3_open(db_path.c_str(), &tmp_sqlite_db);
if (status != SQLITE_OK)
throw Exception(ErrorCodes::PATH_ACCESS_DENIED,
"Failed to open sqlite database. Status: {}. Message: {}",
status, sqlite3_errstr(status));
return StorageSQLite::create(args.table_id, std::shared_ptr<sqlite3>(tmp_sqlite_db, sqlite3_close),
return StorageSQLite::create(args.table_id, sqlite_db,
table_name, args.columns, args.constraints, args.getContext());
},
{

View File

@ -4,9 +4,9 @@
#include <Common/Exception.h>
#include <Common/quoteString.h>
#include <Common/filesystemHelpers.h>
#include <Databases/SQLite/fetchSQLiteTableStructure.h>
#include <Databases/SQLite/SQLiteUtils.h>
#include "registerTableFunctions.h"
#include <Interpreters/evaluateConstantExpression.h>
@ -27,7 +27,6 @@ namespace ErrorCodes
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
extern const int BAD_ARGUMENTS;
extern const int SQLITE_ENGINE_ERROR;
extern const int PATH_ACCESS_DENIED;
}
@ -76,15 +75,7 @@ void TableFunctionSQLite::parseArguments(const ASTPtr & ast_function, ContextPtr
database_path = args[0]->as<ASTLiteral &>().value.safeGet<String>();
remote_table_name = args[1]->as<ASTLiteral &>().value.safeGet<String>();
auto db_path = SQLiteDatabaseValidatePath(database_path, context->getUserFilesPath());
sqlite3 * tmp_sqlite_db = nullptr;
int status = sqlite3_open(db_path.c_str(), &tmp_sqlite_db);
if (status != SQLITE_OK)
throw Exception(ErrorCodes::PATH_ACCESS_DENIED,
"SQLite database file path '{}' must be inside 'user_files' directory: {}", database_path);
sqlite_db = std::shared_ptr<sqlite3>(tmp_sqlite_db, sqlite3_close);
sqlite_db = openSQLiteDB(database_path, context);
}