diff --git a/source/backend/engine/CarlaEngineOscHandlers.cpp b/source/backend/engine/CarlaEngineOscHandlers.cpp index c123fd974..ea0e2ed05 100644 --- a/source/backend/engine/CarlaEngineOscHandlers.cpp +++ b/source/backend/engine/CarlaEngineOscHandlers.cpp @@ -29,10 +29,13 @@ CARLA_BACKEND_START_NAMESPACE // ----------------------------------------------------------------------- -int CarlaEngineOsc::handleMessage(const bool isTCP, const char* const path, const int argc, const lo_arg* const* const argv, const char* const types, const lo_message msg) +int CarlaEngineOsc::handleMessage(const bool isTCP, const char* const path, + const int argc, const lo_arg* const* const argv, const char* const types, + const lo_message msg) { CARLA_SAFE_ASSERT_RETURN(fName.isNotEmpty(), 1); CARLA_SAFE_ASSERT_RETURN(path != nullptr && path[0] != '\0', 1); + CARLA_SAFE_ASSERT_RETURN(path[0] == '/', 1); #ifdef DEBUG if (std::strncmp(path, "/bridge_pong", 12) != 0) { carla_debug("CarlaEngineOsc::handleMessage(%s, \"%s\", %i, %p, \"%s\", %p)", @@ -51,9 +54,11 @@ int CarlaEngineOsc::handleMessage(const bool isTCP, const char* const path, cons CARLA_SAFE_ASSERT_RETURN(fServerUDP != nullptr, 1); } + const lo_address source = lo_message_get_source(msg); + // Initial path check if (std::strcmp(path, "/register") == 0) - return handleMsgRegister(isTCP, argc, argv, types, lo_message_get_source(msg)); + return handleMsgRegister(isTCP, argc, argv, types, source); if (std::strcmp(path, "/unregister") == 0) return handleMsgUnregister(isTCP, argc, argv, types); @@ -64,56 +69,71 @@ int CarlaEngineOsc::handleMessage(const bool isTCP, const char* const path, cons return handleMsgControl(path + 6, argc, argv, types); } - const std::size_t nameSize = fName.length(); - // Check if message is for this client - if (std::strlen(path) <= nameSize || std::strncmp(path+1, fName, nameSize) != 0) + std::size_t bytesAfterName; + if (fControlDataTCP.owner != nullptr && std::strcmp(lo_address_get_hostname(source), fControlDataTCP.owner) == 0) { - carla_stderr("CarlaEngineOsc::handleMessage() - message not for this client -> '%s' != '/%s/'", - path, fName.buffer()); - return 1; + if (const char* const slash = std::strchr(path, '/')) + { + bytesAfterName = static_cast(slash - path) + 1U; + } + else + { + carla_stderr("CarlaEngineOsc::handleMessage() - message '%s' is invalid", path); + return 1; + } + } + else + { + bytesAfterName = fName.length(); + + if (std::strlen(path) <= bytesAfterName || std::strncmp(path+1, fName, bytesAfterName) != 0) + { + carla_stderr("CarlaEngineOsc::handleMessage() - message not for this client -> '%s' != '/%s/'", + path, fName.buffer()); + return 1; + } } // Get plugin id from path, "/carla/23/method" -> 23 uint pluginId = 0; std::size_t offset; - if (std::isdigit(path[nameSize+2])) + if (! std::isdigit(path[bytesAfterName+2])) { - if (std::isdigit(path[nameSize+3])) + carla_stderr("CarlaEngineOsc::handleMessage() - invalid message '%s'", path); + return 1; + } + + if (std::isdigit(path[bytesAfterName+3])) + { + if (std::isdigit(path[bytesAfterName+5])) { - if (std::isdigit(path[nameSize+5])) - { - carla_stderr2("CarlaEngineOsc::handleMessage() - invalid plugin id, over 999? (value: \"%s\")", path+(nameSize+1)); - return 1; - } - else if (std::isdigit(path[nameSize+4])) - { - // 3 digits, /xyz/method - offset = 6; - pluginId += uint(path[nameSize+2]-'0')*100; - pluginId += uint(path[nameSize+3]-'0')*10; - pluginId += uint(path[nameSize+4]-'0'); - } - else - { - // 2 digits, /xy/method - offset = 5; - pluginId += uint(path[nameSize+2]-'0')*10; - pluginId += uint(path[nameSize+3]-'0'); - } + carla_stderr2("CarlaEngineOsc::handleMessage() - invalid plugin id, over 999? (value: \"%s\")", + path+(bytesAfterName+1)); + return 1; + } + else if (std::isdigit(path[bytesAfterName+4])) + { + // 3 digits, /xyz/method + offset = 6; + pluginId += uint(path[bytesAfterName+2]-'0')*100; + pluginId += uint(path[bytesAfterName+3]-'0')*10; + pluginId += uint(path[bytesAfterName+4]-'0'); } else { - // single digit, /x/method - offset = 4; - pluginId += uint(path[nameSize+2]-'0'); + // 2 digits, /xy/method + offset = 5; + pluginId += uint(path[bytesAfterName+2]-'0')*10; + pluginId += uint(path[bytesAfterName+3]-'0'); } } else { - carla_stderr("CarlaEngineOsc::handleMessage() - invalid message '%s'", path); - return 1; + // single digit, /x/method + offset = 4; + pluginId += uint(path[bytesAfterName+2]-'0'); } if (pluginId > fEngine->getCurrentPluginCount()) @@ -133,7 +153,7 @@ int CarlaEngineOsc::handleMessage(const bool isTCP, const char* const path, cons // Get method from path, "/Carla/i/method" -> "method" char method[48]; - std::strncpy(method, path + (nameSize + offset), 47); + std::strncpy(method, path + (bytesAfterName + offset), 47); method[47] = '\0'; if (method[0] == '\0') @@ -221,7 +241,7 @@ int CarlaEngineOsc::handleMsgRegister(const bool isTCP, /* */ char* const port = lo_url_get_port(url); // NOTE: lo_address_get_port is buggy against TCP const lo_address target = lo_address_new_with_proto(isTCP ? LO_TCP : LO_UDP, host, port); - oscData.owner = carla_strdup_safe(url); + oscData.owner = carla_strdup_safe(host); oscData.path = carla_strdup_free(lo_url_get_path(url)); oscData.target = target;