aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2008-02-16 00:32:53 -0800
committerH. Peter Anvin <hpa@zytor.com>2008-02-16 00:32:53 -0800
commit692f55c6ea720972780d47084a4a2146e56003d5 (patch)
treeb1a2dea2fcebe896b7c188c3d2b382d1ac04dad2
parentd3ed8cb31a485cb4263cd22ca5f60c73b6166752 (diff)
downloadsyslinux.git-692f55c6ea720972780d47084a4a2146e56003d5.tar.gz
syslinux.git-692f55c6ea720972780d47084a4a2146e56003d5.tar.xz
syslinux.git-692f55c6ea720972780d47084a4a2146e56003d5.zip
Get rid of 4096-entry limit in the simple menu systemsyslinux-3.62-pre8
Use a dynamic array instead of a static array which we would simply crash on overflow. Always make it a power-of-two sized so we don't end up doing a realloc() and a full array copy on every extend.
-rw-r--r--NEWS1
-rw-r--r--com32/menu/menu.h3
-rw-r--r--com32/menu/readconfig.c41
3 files changed, 35 insertions, 10 deletions
diff --git a/NEWS b/NEWS
index 8626a1d5..fa728b6b 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,7 @@ Changes in 3.62:
* Move the label storage (for the command-line interface) to
high memory, removing the size limit and freeing up 64K of
low memory.
+ * Get rid of 4096-entry limit in the simple menu system.
Changes in 3.61:
* EXTLINUX: fix crash when accessing an empty file.
diff --git a/com32/menu/menu.h b/com32/menu/menu.h
index e8a8f031..87e3215c 100644
--- a/com32/menu/menu.h
+++ b/com32/menu/menu.h
@@ -79,8 +79,7 @@ extern struct messages messages[MSG_COUNT];
/* 2048 is the current definition inside syslinux */
#define MAX_CMDLINE_LEN 2048
-#define MAX_ENTRIES 4096 /* Oughta be enough for anybody */
-extern struct menu_entry menu_entries[];
+extern struct menu_entry *menu_entries;
extern struct menu_entry *menu_hotkeys[256];
struct menu_parameter {
diff --git a/com32/menu/readconfig.c b/com32/menu/readconfig.c
index c5f10183..ab9994e2 100644
--- a/com32/menu/readconfig.c
+++ b/com32/menu/readconfig.c
@@ -40,8 +40,9 @@ char *menu_background = NULL;
struct fkey_help fkeyhelp[12];
-struct menu_entry menu_entries[MAX_ENTRIES];
-struct menu_entry hide_entries[MAX_ENTRIES];
+struct menu_entry *menu_entries = NULL;
+struct menu_entry *hide_entries = NULL;
+static int menu_entries_space = 0, hide_entries_space = 0;
struct menu_entry *menu_hotkeys[256];
struct messages messages[MSG_COUNT] = {
@@ -170,7 +171,18 @@ record(struct labeldata *ld, char *append)
{
char ipoptions[256], *ipp;
int i;
- struct menu_entry *me = &menu_entries[nentries];
+ struct menu_entry *me;
+
+ if (nentries >= menu_entries_space) {
+ if (!menu_entries_space)
+ menu_entries_space = 1;
+ else
+ menu_entries_space <<= 1;
+
+ menu_entries = realloc(menu_entries,
+ menu_entries_space*sizeof *menu_entries);
+ }
+ me = &menu_entries[nentries];
if ( ld->label ) {
char *a, *s;
@@ -182,7 +194,7 @@ record(struct labeldata *ld, char *append)
me->disabled = 0;
if ( ld->menuindent ) {
- char *n = (char *)malloc(ld->menuindent + strlen(me->displayname) + 1);
+ char *n = malloc(ld->menuindent + strlen(me->displayname) + 1);
memset(n, 32, ld->menuindent);
strcpy(n + ld->menuindent, me->displayname);
me->displayname = n;
@@ -252,10 +264,23 @@ record(struct labeldata *ld, char *append)
nentries++;
}
else {
- hide_entries[nhidden].displayname = me->displayname;
- hide_entries[nhidden].label = me->label;
- hide_entries[nhidden].cmdline = me->cmdline;
- hide_entries[nhidden].passwd = me->passwd;
+ struct menu_entry *he;
+
+ if (nhidden >= hide_entries_space) {
+ if (!hide_entries_space)
+ hide_entries_space = 1;
+ else
+ hide_entries_space <<= 1;
+
+ hide_entries = realloc(hide_entries,
+ hide_entries_space*sizeof *hide_entries);
+ }
+ he = &hide_entries[nhidden];
+
+ he->displayname = me->displayname;
+ he->label = me->label;
+ he->cmdline = me->cmdline;
+ he->passwd = me->passwd;
me->displayname = NULL;
me->label = NULL;