Subsonic API: limit size parameter to 500 for various methods

This commit is contained in:
emeric
2023-11-08 22:47:41 +01:00
parent 121d27b5cd
commit b89dfba089
3 changed files with 30 additions and 7 deletions
@@ -185,6 +185,18 @@ namespace API::Subsonic
const std::string _parameterName;
};
class ParameterValueTooHighGenericError : public GenericError
{
public:
ParameterValueTooHighGenericError(std::string_view parameterName, std::size_t max) : _parameterName{ parameterName }, _max{ max } {}
private:
std::string getMessage() const override { return "Parameter '" + _parameterName + "': bad value"; }
const std::string _parameterName;
std::size_t _max;
};
class Response
{
public:
@@ -47,6 +47,8 @@ namespace API::Subsonic
// Optional params
const std::size_t size{ getParameterAs<std::size_t>(context.parameters, "size").value_or(10) };
const std::size_t offset{ getParameterAs<std::size_t>(context.parameters, "offset").value_or(0) };
if (size > 500)
throw ParameterValueTooHighGenericError{ "size", 500 };
const Range range{ offset, size };
@@ -196,7 +198,8 @@ namespace API::Subsonic
{
// Optional params
std::size_t size{ getParameterAs<std::size_t>(context.parameters, "size").value_or(50) };
size = std::min(size, std::size_t{ 500 });
if (size > 500)
throw ParameterValueTooHighGenericError{"size", 500};
auto transaction{ context.dbSession.createSharedTransaction() };
@@ -221,8 +224,9 @@ namespace API::Subsonic
std::string genre{ getMandatoryParameterAs<std::string>(context.parameters, "genre") };
// Optional params
std::size_t size{ getParameterAs<std::size_t>(context.parameters, "count").value_or(10) };
size = std::min(size, std::size_t{ 500 });
std::size_t count{ getParameterAs<std::size_t>(context.parameters, "count").value_or(10) };
if (count > 500)
throw ParameterValueTooHighGenericError{"count", 500};
std::size_t offset{ getParameterAs<std::size_t>(context.parameters, "offset").value_or(0) };
@@ -245,7 +249,7 @@ namespace API::Subsonic
Track::FindParameters params;
params.setClusters({ cluster->getId() });
params.setRange({ offset, size });
params.setRange({ offset, count });
const auto tracks{ Track::find(context.dbSession, params) };
for (const Track::pointer& track : tracks.results)
@@ -57,15 +57,22 @@ namespace API::Subsonic
std::size_t songCount{ getParameterAs<std::size_t>(context.parameters, "songCount").value_or(20) };
std::size_t songOffset{ getParameterAs<std::size_t>(context.parameters, "songOffset").value_or(0) };
if (artistCount > 500)
throw ParameterValueTooHighGenericError{ "artistCount", 500 };
else if (albumCount > 500)
throw ParameterValueTooHighGenericError{ "albumCount", 500 };
else if (songCount > 500)
throw ParameterValueTooHighGenericError{ "songCount", 500 };
Response response{ Response::createOkResponse(context.serverProtocolVersion) };
Response::Node& searchResult2Node{ response.createNode(id3 ? "searchResult3" : "searchResult2") };
auto transaction{ context.dbSession.createSharedTransaction() };
User::pointer user{ User::find(context.dbSession, context.userId) };
if (!user)
throw UserNotAuthorizedError{};
Response response{ Response::createOkResponse(context.serverProtocolVersion) };
Response::Node& searchResult2Node{ response.createNode(id3 ? "searchResult3" : "searchResult2") };
if (artistCount > 0)
{
Artist::FindParameters params;