Make jsons slightly safer
This commit is contained in:
parent
06fd045fc1
commit
c9bbe3b207
@ -26,6 +26,7 @@ add_library(thetvdb SHARED
|
|||||||
thetvdb/tv_rename.cpp
|
thetvdb/tv_rename.cpp
|
||||||
thetvdb/functions.cpp
|
thetvdb/functions.cpp
|
||||||
rename_object.cpp
|
rename_object.cpp
|
||||||
|
functions.cpp
|
||||||
filesystem/unix/filesystem.cpp
|
filesystem/unix/filesystem.cpp
|
||||||
network/unix/network.cpp)
|
network/unix/network.cpp)
|
||||||
|
|
||||||
@ -34,12 +35,14 @@ target_link_libraries(thetvdb curl)
|
|||||||
add_library(simple SHARED
|
add_library(simple SHARED
|
||||||
simple_rename/simple.cpp
|
simple_rename/simple.cpp
|
||||||
rename_object.cpp
|
rename_object.cpp
|
||||||
|
functions.cpp
|
||||||
filesystem/unix/filesystem.cpp)
|
filesystem/unix/filesystem.cpp)
|
||||||
|
|
||||||
add_library(moviedb SHARED
|
add_library(moviedb SHARED
|
||||||
themoviedb/moviedb.cpp
|
themoviedb/moviedb.cpp
|
||||||
themoviedb/functions.cpp
|
themoviedb/functions.cpp
|
||||||
rename_object.cpp
|
rename_object.cpp
|
||||||
|
functions.cpp
|
||||||
filesystem/unix/filesystem.cpp
|
filesystem/unix/filesystem.cpp
|
||||||
network/unix/network.cpp)
|
network/unix/network.cpp)
|
||||||
|
|
||||||
|
@ -88,3 +88,17 @@ std::vector< std::string > getTargetDirectories( const std::string &target_dir )
|
|||||||
std::sort(result.begin(), result.end());
|
std::sort(result.begin(), result.end());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string safeJson(std::string input) {
|
||||||
|
for(size_t i = 0; i < input.size(); i++) {
|
||||||
|
if(input[i] == '\\') {
|
||||||
|
input.insert(i, "\\");
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if(input[i] == '"') {
|
||||||
|
input.insert(i, "\\");
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
@ -8,5 +8,6 @@ std::vector< RenameLibrary > getLibraries(const std::vector<std::pair<std::strin
|
|||||||
void closeLibraries( std::vector< RenameLibrary > &libraries );
|
void closeLibraries( std::vector< RenameLibrary > &libraries );
|
||||||
std::vector< std::string > getFilesInSource( const std::string &source_dir );
|
std::vector< std::string > getFilesInSource( const std::string &source_dir );
|
||||||
std::vector< std::string > getTargetDirectories( const std::string &target_dir );
|
std::vector< std::string > getTargetDirectories( const std::string &target_dir );
|
||||||
|
std::string safeJson(std::string input);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
88
main.cpp
88
main.cpp
@ -68,24 +68,27 @@ std::vector<std::pair<std::string, size_t>> getTypes() {
|
|||||||
std::string getTypesJson() {
|
std::string getTypesJson() {
|
||||||
auto types = getTypes();
|
auto types = getTypes();
|
||||||
std::ostringstream result;
|
std::ostringstream result;
|
||||||
result << "[\n";
|
result << "{\n \"types\": [\n";
|
||||||
if(!types.empty()) {
|
if(!types.empty()) {
|
||||||
for(const auto &type : types) {
|
for(const auto &type : types) {
|
||||||
result << " {\n \"id\": " << type.second << "\n";
|
result << " {\n \"id\": " << type.second << ",\n";
|
||||||
result << " \"name\": \"" << type.first << "\"\n },\n";
|
result << " \"name\": \"" << safeJson(type.first) << "\"\n },\n";
|
||||||
}
|
}
|
||||||
result.seekp(-2, std::ios_base::end);
|
result.seekp(-2, std::ios_base::end);
|
||||||
result << "\n";
|
result << "\n";
|
||||||
}
|
}
|
||||||
result << "]";
|
result << " ]\n}";
|
||||||
return result.str();
|
auto res = result.str();
|
||||||
|
std::cout << res << std::endl;
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getTypesRest( const std::shared_ptr< restbed::Session > &session ) {
|
void getTypesRest( const std::shared_ptr< restbed::Session > &session ) {
|
||||||
sendResponse(getTypesJson(), restbed::OK, session);
|
sendResponse(getTypesJson(), restbed::OK, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector< RenameObject > getOptions(const RenameObject &search, size_t type) {
|
std::vector< RenameObject > getOptions(const RenameObject &search) {
|
||||||
|
auto type = search.getLibraryId();
|
||||||
if(type >= libraries.size()) {
|
if(type >= libraries.size()) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -96,10 +99,10 @@ std::vector< RenameObject > getOptions(const RenameObject &search, size_t type)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getOptionsJson(const RenameObject &search, size_t type) {
|
std::string getOptionsJson(const RenameObject &search) {
|
||||||
std::ostringstream res;
|
std::ostringstream res;
|
||||||
res << "[\n";
|
res << "{\n \"options\": [\n";
|
||||||
auto options = getOptions(search, type);
|
auto options = getOptions(search);
|
||||||
if(!options.empty()) {
|
if(!options.empty()) {
|
||||||
for(auto &option : options) {
|
for(auto &option : options) {
|
||||||
res << option.toJson();
|
res << option.toJson();
|
||||||
@ -108,8 +111,10 @@ std::string getOptionsJson(const RenameObject &search, size_t type) {
|
|||||||
res.seekp( -2, std::ios_base::end );
|
res.seekp( -2, std::ios_base::end );
|
||||||
res << "\n";
|
res << "\n";
|
||||||
}
|
}
|
||||||
res << "]";
|
res << " ]\n}";
|
||||||
return res.str();
|
auto result = res.str();
|
||||||
|
std::cout << result << std::endl;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getOptionsRest( const std::shared_ptr< restbed::Session > &session, rapidjson::GenericDocument<rapidjson::UTF8<>> &doc )
|
void getOptionsRest( const std::shared_ptr< restbed::Session > &session, rapidjson::GenericDocument<rapidjson::UTF8<>> &doc )
|
||||||
@ -121,26 +126,21 @@ void getOptionsRest( const std::shared_ptr< restbed::Session > &session, rapidjs
|
|||||||
if(!verifyLogin(session, doc)) {
|
if(!verifyLogin(session, doc)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(doc.FindMember("type") == doc.MemberEnd() || !doc["type"].IsUint64()) {
|
if(doc.FindMember("info") == doc.MemberEnd() || !doc["info"].IsObject()) {
|
||||||
sendResponse("ERROR: Invalid type!", 401, session);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(doc.FindMember("search") == doc.MemberEnd() || !doc["search"].IsObject()) {
|
|
||||||
sendResponse("ERROR: Invalid search!", 401, session);
|
sendResponse("ERROR: Invalid search!", 401, session);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
size_t type_id = doc["type"].GetUint64();
|
|
||||||
RenameObject search;
|
RenameObject search;
|
||||||
rapidjson::StringBuffer sb;
|
rapidjson::StringBuffer sb;
|
||||||
rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
|
rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
|
||||||
doc["search"].Accept(writer);
|
doc["info"].Accept(writer);
|
||||||
std::string s = sb.GetString();
|
std::string s = sb.GetString();
|
||||||
search.fromJson(s);
|
search.fromJson(s);
|
||||||
if(search.getPresentedName().empty()) {
|
if(search.getPresentedName().empty()) {
|
||||||
sendResponse("Empty search", 401, session);
|
sendResponse("Empty search", 401, session);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sendResponse(getOptionsJson(search, type_id), 200, session);
|
sendResponse(getOptionsJson(search), 200, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector< std::string > getCustomKeys(size_t type) {
|
std::vector< std::string > getCustomKeys(size_t type) {
|
||||||
@ -153,16 +153,16 @@ std::vector< std::string > getCustomKeys(size_t type) {
|
|||||||
|
|
||||||
std::string getCustomKeysJson(size_t type) {
|
std::string getCustomKeysJson(size_t type) {
|
||||||
std::ostringstream res;
|
std::ostringstream res;
|
||||||
res << "[\n";
|
res << "{\n \"custom_keys\": [\n";
|
||||||
auto custom_keys = getCustomKeys(type);
|
auto custom_keys = getCustomKeys(type);
|
||||||
if(!custom_keys.empty()) {
|
if(!custom_keys.empty()) {
|
||||||
for(auto &key : custom_keys) {
|
for(auto &key : custom_keys) {
|
||||||
res << "\"" << key << "\",\n";
|
res << "\"" << safeJson(key) << "\",\n";
|
||||||
}
|
}
|
||||||
res.seekp( -2, std::ios_base::end );
|
res.seekp( -2, std::ios_base::end );
|
||||||
res << "\n";
|
res << "\n";
|
||||||
}
|
}
|
||||||
res << "]";
|
res << " ]\n}";
|
||||||
return res.str();
|
return res.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,9 +204,9 @@ std::string renamePathJson(const std::string &path, const RenameObject &renamer)
|
|||||||
} else {
|
} else {
|
||||||
res << "false";
|
res << "false";
|
||||||
}
|
}
|
||||||
res << "\"\n";
|
res << "\n";
|
||||||
if(!rename_result.first) {
|
if(!rename_result.first) {
|
||||||
res << " \"error\": \"" << rename_result.second << "\"\n";
|
res << " \"error\": \"" << safeJson(rename_result.second) << "\"\n";
|
||||||
}
|
}
|
||||||
res << "}";
|
res << "}";
|
||||||
return res.str();
|
return res.str();
|
||||||
@ -221,15 +221,15 @@ void renamePathRest( const std::shared_ptr< restbed::Session > &session, rapidjs
|
|||||||
sendResponse("ERROR: Invalid path!", 401, session);
|
sendResponse("ERROR: Invalid path!", 401, session);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(doc.FindMember("renamer") == doc.MemberEnd() || !doc["renamer"].IsObject()) {
|
if(doc.FindMember("info") == doc.MemberEnd() || !doc["info"].IsObject()) {
|
||||||
sendResponse("ERROR: Invalid renamer!", 401, session);
|
sendResponse("ERROR: Invalid info!", 401, session);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::string path = doc["path"].GetString();
|
std::string path = doc["path"].GetString();
|
||||||
RenameObject renamer;
|
RenameObject renamer;
|
||||||
rapidjson::StringBuffer sb;
|
rapidjson::StringBuffer sb;
|
||||||
rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
|
rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
|
||||||
doc["renamer"].Accept(writer);
|
doc["info"].Accept(writer);
|
||||||
std::string s = sb.GetString();
|
std::string s = sb.GetString();
|
||||||
renamer.fromJson(s);
|
renamer.fromJson(s);
|
||||||
sendResponse(renamePathJson(path, renamer), 200, session);
|
sendResponse(renamePathJson(path, renamer), 200, session);
|
||||||
@ -237,15 +237,15 @@ void renamePathRest( const std::shared_ptr< restbed::Session > &session, rapidjs
|
|||||||
|
|
||||||
std::string getFilesJson() {
|
std::string getFilesJson() {
|
||||||
std::ostringstream res;
|
std::ostringstream res;
|
||||||
res << "[\n";
|
res << "{\n \"files\": [\n";
|
||||||
auto files = getFilesInSource(cfg.getSourcePath());
|
auto files = getFilesInSource(cfg.getSourcePath());
|
||||||
if(!files.empty()) {
|
if(!files.empty()) {
|
||||||
for(const auto &file : files) {
|
for(const auto &file : files) {
|
||||||
res << "\"" << file << "\",\n";
|
res << "\"" << safeJson(file) << "\",\n";
|
||||||
}
|
}
|
||||||
res.seekp(-2, std::ios_base::end);
|
res.seekp(-2, std::ios_base::end);
|
||||||
}
|
}
|
||||||
res << "\n]";
|
res << "\n ]\n}";
|
||||||
return res.str();
|
return res.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,16 +268,16 @@ std::vector<std::pair<uint64_t, std::string>> getTargets() {
|
|||||||
|
|
||||||
std::string getTargetsJson() {
|
std::string getTargetsJson() {
|
||||||
std::ostringstream res;
|
std::ostringstream res;
|
||||||
res << "[\n";
|
res << "{\n \"targets\": [\n";
|
||||||
auto targets = getTargets();
|
auto targets = getTargets();
|
||||||
if(!targets.empty()) {
|
if(!targets.empty()) {
|
||||||
for(const auto &target : targets) {
|
for(const auto &target : targets) {
|
||||||
res << " {\n" << " \"id\": " << target.first << "\n";
|
res << " {\n" << " \"id\": " << target.first << "\n";
|
||||||
res << " \"name\": \"" << target.second << "\"\n },\n";
|
res << " \"name\": \"" << safeJson(target.second) << "\"\n },\n";
|
||||||
}
|
}
|
||||||
res.seekp(-2, std::ios_base::end);
|
res.seekp(-2, std::ios_base::end);
|
||||||
}
|
}
|
||||||
res << "\n]";
|
res << "\n ]\n}";
|
||||||
return res.str();
|
return res.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,15 +294,15 @@ std::string getTargetDirectoriesJson(uint64_t id) {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
std::ostringstream res;
|
std::ostringstream res;
|
||||||
res << "[\n";
|
res << "{\n \"target_directories\": [\n";
|
||||||
auto dirs = getTargetDirectories(cfg.getTargetPaths()[id].first);
|
auto dirs = getTargetDirectories(cfg.getTargetPaths()[id].first);
|
||||||
if(!dirs.empty()) {
|
if(!dirs.empty()) {
|
||||||
for(const auto &dir : dirs) {
|
for(const auto &dir : dirs) {
|
||||||
res << " \"" << dir << "\",\n";
|
res << " \"" << safeJson(dir) << "\",\n";
|
||||||
}
|
}
|
||||||
res.seekp(-2, std::ios_base::end);
|
res.seekp(-2, std::ios_base::end);
|
||||||
}
|
}
|
||||||
res << "\n]";
|
res << "\n ]\n}";
|
||||||
return res.str();
|
return res.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,9 +351,9 @@ std::string moveJson(const std::string &path, uint64_t target_id, const std::str
|
|||||||
} else {
|
} else {
|
||||||
res << "false";
|
res << "false";
|
||||||
}
|
}
|
||||||
res << "\"\n";
|
res << "\n";
|
||||||
if(!move_result.first) {
|
if(!move_result.first) {
|
||||||
res << " \"error\": \"" << move_result.second << "\"\n";
|
res << " \"error\": \"" << safeJson(move_result.second) << "\"\n";
|
||||||
}
|
}
|
||||||
res << "}";
|
res << "}";
|
||||||
return res.str();
|
return res.str();
|
||||||
@ -408,9 +408,9 @@ std::string removeJson(const std::string &path) {
|
|||||||
} else {
|
} else {
|
||||||
res << "false";
|
res << "false";
|
||||||
}
|
}
|
||||||
res << "\"\n";
|
res << "\n";
|
||||||
if(!remove_result.first) {
|
if(!remove_result.first) {
|
||||||
res << " \"error\": \"" << remove_result.second << "\"\n";
|
res << " \"error\": \"" << safeJson(remove_result.second) << "\"\n";
|
||||||
}
|
}
|
||||||
res << "}";
|
res << "}";
|
||||||
return res.str();
|
return res.str();
|
||||||
@ -431,6 +431,12 @@ void removeRest( const std::shared_ptr< restbed::Session > &session, rapidjson::
|
|||||||
sendResponse(removeJson(path), 200, session);
|
sendResponse(removeJson(path), 200, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string loginJson(const std::string &user) {
|
||||||
|
std::ostringstream res;
|
||||||
|
res << "{\n \"token\": \"" << createLoginToken(user) << "\"\n}";
|
||||||
|
return res.str();
|
||||||
|
}
|
||||||
|
|
||||||
void loginRest( const std::shared_ptr< restbed::Session > &session, rapidjson::GenericDocument<rapidjson::UTF8<>> &doc ) {
|
void loginRest( const std::shared_ptr< restbed::Session > &session, rapidjson::GenericDocument<rapidjson::UTF8<>> &doc ) {
|
||||||
if(doc.FindMember("user") == doc.MemberEnd() || !doc["user"].IsString()) {
|
if(doc.FindMember("user") == doc.MemberEnd() || !doc["user"].IsString()) {
|
||||||
sendResponse("ERROR: Invalid user!", 401, session);
|
sendResponse("ERROR: Invalid user!", 401, session);
|
||||||
@ -450,7 +456,7 @@ void loginRest( const std::shared_ptr< restbed::Session > &session, rapidjson::G
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(valid) {
|
if(valid) {
|
||||||
sendResponse(createLoginToken(user), 200, session);
|
sendResponse(loginJson(user), 200, session);
|
||||||
} else {
|
} else {
|
||||||
sendResponse("Invalid user/password", 401, session);
|
sendResponse("Invalid user/password", 401, session);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "rename_object.hpp"
|
#include "rename_object.hpp"
|
||||||
|
#include "functions.hpp"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <rapidjson/document.h>
|
#include <rapidjson/document.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -35,11 +36,11 @@ void RenameObject::clearCustomFields() {
|
|||||||
std::string RenameObject::toJson() const {
|
std::string RenameObject::toJson() const {
|
||||||
std::ostringstream result;
|
std::ostringstream result;
|
||||||
result << "{\n \"library_id\": " << _library_id << ",\n";
|
result << "{\n \"library_id\": " << _library_id << ",\n";
|
||||||
result << " \"name\": \"" << _name << "\",\n";
|
result << " \"name\": \"" << safeJson(_name) << "\",\n";
|
||||||
result << " \"custom_fields\": {\n";
|
result << " \"custom_fields\": {\n";
|
||||||
if ( _custom_fields.size() > 0 ) {
|
if ( _custom_fields.size() > 0 ) {
|
||||||
for ( auto &entry : _custom_fields ) {
|
for ( auto &entry : _custom_fields ) {
|
||||||
result << " \"" << entry.first << "\": \"" << entry.second
|
result << " \"" << safeJson(entry.first) << "\": \"" << safeJson(entry.second)
|
||||||
<< "\",\n";
|
<< "\",\n";
|
||||||
}
|
}
|
||||||
result.seekp( -2, std::ios_base::end );
|
result.seekp( -2, std::ios_base::end );
|
||||||
|
@ -56,6 +56,10 @@ bool init(const string &config_path) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hasKey(const rapidjson::GenericValue<rapidjson::UTF8<>> &object, const std::string &key) {
|
||||||
|
return object.FindMember(key.c_str()) != object.MemberEnd();
|
||||||
|
}
|
||||||
|
|
||||||
std::vector< std::tuple< string, string, string, string > >
|
std::vector< std::tuple< string, string, string, string > >
|
||||||
searchMovie( const string &movie, const string &language, const string &year ) {
|
searchMovie( const string &movie, const string &language, const string &year ) {
|
||||||
Request &request = _moviedb_request;
|
Request &request = _moviedb_request;
|
||||||
@ -89,6 +93,10 @@ searchMovie( const string &movie, const string &language, const string &year ) {
|
|||||||
|
|
||||||
// find all possible movies
|
// find all possible movies
|
||||||
for ( size_t i = 0; i < results.Size(); i++ ) {
|
for ( size_t i = 0; i < results.Size(); i++ ) {
|
||||||
|
if(!hasKey(results[i], "title") || !hasKey(results[i], "id") ||
|
||||||
|
!hasKey(results[i], "release_date") || !hasKey(results[i], "original_title")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
auto movie = toString( results[i]["title"].GetString() );
|
auto movie = toString( results[i]["title"].GetString() );
|
||||||
auto id = toString( std::to_string( results[i]["id"].GetInt() ) );
|
auto id = toString( std::to_string( results[i]["id"].GetInt() ) );
|
||||||
string year = toString( results[i]["release_date"].GetString() );
|
string year = toString( results[i]["release_date"].GetString() );
|
||||||
|
Loading…
Reference in New Issue
Block a user