Fix wildcard routing precedence bug, fuzz router
This commit is contained in:
+47
-2
@@ -5,9 +5,48 @@
|
|||||||
/* We test the websocket parser */
|
/* We test the websocket parser */
|
||||||
#include "../src/HttpParser.h"
|
#include "../src/HttpParser.h"
|
||||||
|
|
||||||
|
/* And the router */
|
||||||
|
#include "../src/HttpRouter.h"
|
||||||
|
|
||||||
/* We use this to pad the fuzz */
|
/* We use this to pad the fuzz */
|
||||||
char *padded = new char[1024 * 500];
|
char *padded = new char[1024 * 500];
|
||||||
|
|
||||||
|
struct StaticData {
|
||||||
|
|
||||||
|
struct RouterData {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
uWS::HttpRouter<RouterData> router;
|
||||||
|
|
||||||
|
StaticData() {
|
||||||
|
|
||||||
|
router.add("get", "/:hello/:hi", [](RouterData &user, std::pair<int, std::string_view *> params) mutable {
|
||||||
|
|
||||||
|
/* This route did handle it */
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
router.add("post", "/:hello/:hi/*", [](RouterData &user, std::pair<int, std::string_view *> params) mutable {
|
||||||
|
|
||||||
|
/* This route did handle it */
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
router.add("get", "/*", [](RouterData &user, std::pair<int, std::string_view *> params) mutable {
|
||||||
|
|
||||||
|
/* This route did not handle it */
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
router.add("get", "/hi", [](RouterData &user, std::pair<int, std::string_view *> params) mutable {
|
||||||
|
|
||||||
|
/* This route did handle it */
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} staticData;
|
||||||
|
|
||||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||||
|
|
||||||
/* Pad the fuzz */
|
/* Pad the fuzz */
|
||||||
@@ -22,11 +61,17 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
|||||||
|
|
||||||
/* todo: Route this via router */
|
/* todo: Route this via router */
|
||||||
|
|
||||||
httpRequest->getHeader("get");
|
httpRequest->getHeader(httpRequest->getUrl());
|
||||||
httpRequest->getUrl();
|
|
||||||
httpRequest->getMethod();
|
httpRequest->getMethod();
|
||||||
httpRequest->getQuery();
|
httpRequest->getQuery();
|
||||||
|
|
||||||
|
/* Route the method and URL in two passes */
|
||||||
|
StaticData::RouterData routerData = {};
|
||||||
|
if (!staticData.router.route(httpRequest->getMethod(), httpRequest->getUrl(), routerData)) {
|
||||||
|
/* It was not handled */
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto p : *httpRequest) {
|
for (auto p : *httpRequest) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-13
@@ -79,7 +79,7 @@ private:
|
|||||||
/* Set URL for router. Will reset any URL cache */
|
/* Set URL for router. Will reset any URL cache */
|
||||||
inline void setUrl(std::string_view url) {
|
inline void setUrl(std::string_view url) {
|
||||||
/* Remove / from input URL */
|
/* Remove / from input URL */
|
||||||
currentUrl = url.substr(1);
|
currentUrl = url.substr(std::min<unsigned int>(url.length(), 1));
|
||||||
urlSegmentTop = -1;
|
urlSegmentTop = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +133,10 @@ private:
|
|||||||
/* Wildcard match (can be seen as a shortcut) */
|
/* Wildcard match (can be seen as a shortcut) */
|
||||||
int handlerIndex = p->handler;
|
int handlerIndex = p->handler;
|
||||||
if (handlerIndex) {
|
if (handlerIndex) {
|
||||||
return handlers[handlerIndex](userData, {routeParameters.paramsTop, routeParameters.params});
|
int handler = handlers[handlerIndex](userData, {routeParameters.paramsTop, routeParameters.params});
|
||||||
|
if (handler) {
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Unhandled */
|
/* Unhandled */
|
||||||
return false;
|
return false;
|
||||||
@@ -264,21 +267,16 @@ public:
|
|||||||
routeParameters.reset();
|
routeParameters.reset();
|
||||||
|
|
||||||
/* Begin by finding the method node */
|
/* Begin by finding the method node */
|
||||||
Node *parent = &tree;
|
for (auto &p : tree.children) {
|
||||||
for (auto &p : parent->children) {
|
|
||||||
if (p->name == method) {
|
if (p->name == method) {
|
||||||
parent = p;
|
/* Then route the url */
|
||||||
|
return executeHandlers(p, 0, userData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We have that method on record, let's iterate it */
|
/* We did not find any handler for this method.
|
||||||
if (parent != &tree) {
|
* You may want to re-route with "*" as method. */
|
||||||
return executeHandlers(parent, 0, userData);
|
return false;
|
||||||
} else {
|
|
||||||
/* We did not find any handler for this method.
|
|
||||||
* You may want to re-route with "*" as method. */
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user