Get rid of 4096-entry limit in the simple menu system syslinux-3.62-pre8
authorH. Peter Anvin <hpa@zytor.com>
Sat, 16 Feb 2008 08:32:53 +0000 (00:32 -0800)
committerH. Peter Anvin <hpa@zytor.com>
Sat, 16 Feb 2008 08:32:53 +0000 (00:32 -0800)
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.

NEWS
com32/menu/menu.h
com32/menu/readconfig.c

diff --git a/NEWS b/NEWS
index 8626a1d..fa728b6 100644 (file)
--- 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.
index e8a8f03..87e3215 100644 (file)
@@ -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 {
index c5f1018..ab9994e 100644 (file)
@@ -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;