alliedmodders/amxmodx — pull request #20 by Nextra (2014-05-21 22:45:00+00:00)
Title: Newmenus: Add MEXIT_FORCE and fix possible crash

While working with newmenus in the recent days I noticed that it is impossible to add a proper exit button to non-paginated menus (having ```MPROP_PERPAGE``` set to 0). The part of ```Menu::GetTextString``` skips anything related to back/next/exit buttons when pagination is disabled. To change this *and* preserve all previous behavior I added ```MEXIT_FORCE```. Setting ```MPROP_EXIT``` to this value will add a proper exit button to a non-paginated menu. Similar to the default pagination behavior the exit button is not automatically padded to be located at the 10th slot, but that can be achieved using ```menu_addblank2```.

--

While playing around with my test plugin I noticed that an underflow bug can occur when a non-paginated menu has no items in it. ```menuItems - 1``` will wrap and subsequently set ```end = 10```. Running the loop with this will immediately cause a segfault when accessing ```m_Items```. This is also fixed.

--

Test plugin I used to test various item/pagination/exit configurations:
```SourcePawn
#include

public plugin_init() {
register_clcmd("menutest", "menutest");
}

public menutest(const client) {
if (read_argc() != 4) {
return PLUGIN_HANDLED;
}

new arg[32];
read_argv(1, arg, charsmax(arg));
new count = clamp(strtol(arg), 0, 10);
read_argv(2, arg, charsmax(arg));
new perpage = clamp(strtol(arg), 0, 7);
read_argv(3, arg, charsmax(arg));
new mexit = clamp(strtol(arg), -1, 2);

new menu = menu_create("Menu Test", "_handler");
menu_setprop(menu, MPROP_PERPAGE, perpage);
menu_setprop(menu, MPROP_EXIT, mexit);

for (new i = 0; i < count; ++i) {
menu_additem(menu, "Test");
}

menu_display(client, menu);

return PLUGIN_HANDLED;
}

public _handler(const client, const menu, const item) {
client_print(client, print_chat, "_handler(%d, %d, %d)", client, menu, item);
menu_destroy(menu);
}
```