Check language_pack and language_code for validness.
GitOrigin-RevId: bc4907a06f74af8bdda9e8bdec82e7a3ce788580
This commit is contained in:
parent
3d7c4426f6
commit
9b6382d5d0
@ -19,6 +19,7 @@
|
||||
#include "td/db/SqliteKeyValue.h"
|
||||
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
#include <atomic>
|
||||
@ -41,6 +42,7 @@ struct LanguagePackManager::Language {
|
||||
std::unordered_map<string, string> ordinary_strings_;
|
||||
std::unordered_map<string, PluralizedString> pluralized_strings_;
|
||||
std::unordered_set<string> deleted_strings_;
|
||||
SqliteKeyValue kv_; // usages should be guarded by database_->mutex_
|
||||
};
|
||||
|
||||
struct LanguagePackManager::LanguagePack {
|
||||
@ -57,6 +59,24 @@ struct LanguagePackManager::LanguageDatabase {
|
||||
|
||||
LanguagePackManager::~LanguagePackManager() = default;
|
||||
|
||||
bool LanguagePackManager::check_language_pack_name(Slice name) {
|
||||
for (auto c : name) {
|
||||
if (c != '_' && !is_alpha(c)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LanguagePackManager::check_language_code_name(Slice name) {
|
||||
for (auto c : name) {
|
||||
if (!is_alpha(c)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return name.size() == 2 || name.empty();
|
||||
}
|
||||
|
||||
static Result<SqliteDb> open_database(const string &path) {
|
||||
TRY_RESULT(database, SqliteDb::open_with_key(path, DbKey::empty()));
|
||||
TRY_STATUS(database.exec("PRAGMA synchronous=NORMAL"));
|
||||
@ -71,6 +91,8 @@ void LanguagePackManager::start_up() {
|
||||
manager_count_++;
|
||||
language_pack_ = G()->shared_config().get_option_string("language_pack");
|
||||
language_code_ = G()->shared_config().get_option_string("language_code");
|
||||
CHECK(check_language_pack_name(language_pack_));
|
||||
CHECK(check_language_code_name(language_code_));
|
||||
|
||||
string database_path = G()->shared_config().get_option_string("language_database_path");
|
||||
auto it = language_databases_.find(database_path);
|
||||
@ -117,6 +139,7 @@ void LanguagePackManager::on_language_pack_changed() {
|
||||
}
|
||||
|
||||
language_pack_ = std::move(new_language_pack);
|
||||
CHECK(check_language_pack_name(language_pack_));
|
||||
inc_generation();
|
||||
}
|
||||
|
||||
@ -127,6 +150,7 @@ void LanguagePackManager::on_language_code_changed() {
|
||||
}
|
||||
|
||||
language_code_ = std::move(new_language_code);
|
||||
CHECK(check_language_code_name(language_code_));
|
||||
inc_generation();
|
||||
}
|
||||
|
||||
@ -231,6 +255,10 @@ LanguagePackManager::Language *LanguagePackManager::get_language(LanguagePack *l
|
||||
return it->second.get();
|
||||
}
|
||||
|
||||
static string get_database_table_name(const string &language_pack, const string &language_code) {
|
||||
return PSTRING() << language_pack << "_" << language_code;
|
||||
}
|
||||
|
||||
LanguagePackManager::Language *LanguagePackManager::add_language(LanguageDatabase *database,
|
||||
const string &language_pack,
|
||||
const string &language_code) {
|
||||
@ -245,6 +273,9 @@ LanguagePackManager::Language *LanguagePackManager::add_language(LanguageDatabas
|
||||
auto code_it = pack->languages_.find(language_code);
|
||||
if (code_it == pack->languages_.end()) {
|
||||
code_it = pack->languages_.emplace(language_code, make_unique<Language>()).first;
|
||||
code_it->second->kv_
|
||||
.init_with_connection(database->database_.clone(), get_database_table_name(language_pack, language_code))
|
||||
.ensure();
|
||||
}
|
||||
return code_it->second.get();
|
||||
}
|
||||
|
@ -34,6 +34,10 @@ class LanguagePackManager : public NetQueryCallback {
|
||||
LanguagePackManager &operator=(LanguagePackManager &&) = delete;
|
||||
~LanguagePackManager() override;
|
||||
|
||||
static bool check_language_pack_name(Slice name);
|
||||
|
||||
static bool check_language_code_name(Slice name);
|
||||
|
||||
void on_language_pack_changed();
|
||||
|
||||
void on_language_code_changed();
|
||||
|
@ -6070,7 +6070,7 @@ void Td::on_request(uint64 id, td_api::setOption &request) {
|
||||
return false;
|
||||
};
|
||||
|
||||
auto set_string_option = [&](Slice name) {
|
||||
auto set_string_option = [&](Slice name, auto check_value) {
|
||||
if (request.name_ == name) {
|
||||
if (value_constructor_id != td_api::optionValueString::ID &&
|
||||
value_constructor_id != td_api::optionValueEmpty::ID) {
|
||||
@ -6080,8 +6080,17 @@ void Td::on_request(uint64 id, td_api::setOption &request) {
|
||||
if (value_constructor_id == td_api::optionValueEmpty::ID) {
|
||||
G()->shared_config().set_option_empty(name);
|
||||
} else {
|
||||
G()->shared_config().set_option_string(name,
|
||||
static_cast<td_api::optionValueString *>(request.value_.get())->value_);
|
||||
const string &value = static_cast<td_api::optionValueString *>(request.value_.get())->value_;
|
||||
if (value.empty()) {
|
||||
G()->shared_config().set_option_empty(name);
|
||||
} else {
|
||||
if (check_value(value)) {
|
||||
G()->shared_config().set_option_string(name, value);
|
||||
} else {
|
||||
send_error_raw(id, 3, PSLICE() << "Option \"" << name << "\" can't have specified value");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
send_closure(actor_id(this), &Td::send_result, id, make_tl_object<td_api::ok>());
|
||||
return true;
|
||||
@ -6107,13 +6116,13 @@ void Td::on_request(uint64 id, td_api::setOption &request) {
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
if (set_string_option("language_database_path")) {
|
||||
if (set_string_option("language_database_path", [](Slice value) { return true; })) {
|
||||
return;
|
||||
}
|
||||
if (set_string_option("language_pack")) {
|
||||
if (set_string_option("language_pack", LanguagePackManager::check_language_pack_name)) {
|
||||
return;
|
||||
}
|
||||
if (set_string_option("language_code")) {
|
||||
if (set_string_option("language_code", LanguagePackManager::check_language_code_name)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
Reference in New Issue
Block a user