Bloody off-by-1 error for a malloc, leading to ever-so-slight memory corruption....
[pandora-libraries.git] / minimenu / mmcat.c
index c4a0533..ab3e9d4 100644 (file)
@@ -39,6 +39,12 @@ void category_init ( void ) {
   return;
 }
 
+static char *_normalize ( char *catname, char *parentcatname ) {
+  static char buffer [ 101 ];
+  snprintf ( buffer, 100, "%s*%s", catname, parentcatname ? parentcatname : "NoParent" );
+  return ( buffer );
+}
+
 unsigned char category_push ( char *catname, char *parentcatname, pnd_disco_t *app, pnd_conf_handle ovrh, char *fspath, unsigned char visiblep ) {
   mm_category_t *c;
 
@@ -51,12 +57,12 @@ unsigned char category_push ( char *catname, char *parentcatname, pnd_disco_t *a
   // find or create category
   //
 
-  if ( ( c = pnd_box_find_by_key ( m_categories, catname ) ) ) {
+  if ( ( c = pnd_box_find_by_key ( m_categories, _normalize ( catname, parentcatname ) ) ) ) {
     // category was found..
   } else {
     // category wasn't found..
     //pnd_log ( PND_LOG_DEFAULT, "New category '%s'\n", catname );
-    c = pnd_box_allocinsert ( m_categories, catname, sizeof(mm_category_t) );
+    c = pnd_box_allocinsert ( m_categories, _normalize ( catname, parentcatname ), sizeof(mm_category_t) );
     c -> catname = strdup ( catname );
     if ( parentcatname ) {
       c -> parent_catname = strdup ( parentcatname );
@@ -291,7 +297,7 @@ unsigned char category_map_setup ( void ) {
        //pnd_log ( pndn_debug, "target(%s) from(%s)\n", k, buffer );
 
        category_push ( k, NULL /* parent cat */, NULL, 0, NULL /* fspath */, 1 );
-       g_catmaps [ g_catmapcount ].target = pnd_box_find_by_key ( m_categories, k );
+       g_catmaps [ g_catmapcount ].target = pnd_box_find_by_key ( m_categories, _normalize ( k, NULL /* TBD: hack, not sure if this is right default value */ ) );
        g_catmaps [ g_catmapcount ].from = strdup ( buffer );
        g_catmapcount++;
 
@@ -336,7 +342,7 @@ unsigned char category_meta_push ( char *catname, char *parentcatname, pnd_disco
   }
 
   // check if category came from an ovr-file; if so, we implicitly trust it instead of enforcing rules
-  if ( app -> object_flags & ( PND_DISCO_CUSTOM1 | PND_DISCO_CUSTOM1 ) ) {
+  if ( app -> object_flags & ( PND_DISCO_CUSTOM1 | PND_DISCO_CUSTOM2 ) ) {
     goto category_done_audit;
   }
 
@@ -348,19 +354,19 @@ unsigned char category_meta_push ( char *catname, char *parentcatname, pnd_disco
 
   unsigned char cat_is_clean = 1;
   freedesktop_cat_t *fdcat = NULL, *fdpcat = NULL;
-  fdcat = freedesktop_category_query ( catname );
+  fdcat = freedesktop_category_query ( catname, parentcatname );
   if ( parentcatname ) {
-    fdpcat = freedesktop_category_query ( parentcatname );
+    fdpcat = freedesktop_category_query ( parentcatname, NULL );
   }
 
   // ensure requested cat is good
   if ( ! fdcat ) {
     // requested cat is bad, send it to Other
     cat_is_clean = 0;
-    printf ( "PXML Fail %s: Cat request %s (parent %s) -> bad cat\n", app -> title_en ? app -> title_en : "no name?", catname, parentcatname ? parentcatname : "n/a" );
+    pnd_log ( pndn_warning, "PXML Fail %s: Cat request %s (parent %s) -> bad cat\n", app -> title_en ? app -> title_en : "no name?", catname, parentcatname ? parentcatname : "n/a" );
 
     // do the Other substitution right away, so remaining code has something to look at in fdcat
-    fdcat = freedesktop_category_query ( BADCATNAME );
+    fdcat = freedesktop_category_query ( BADCATNAME, NULL );
     catname = fdcat -> cat;
     fdpcat = NULL;
     parentcatname = NULL;
@@ -375,7 +381,7 @@ unsigned char category_meta_push ( char *catname, char *parentcatname, pnd_disco
     if ( ! fdpcat ) {
       // requested cat is bad, send it to Other
       cat_is_clean = 0;
-      printf ( "PXML Fail %s: Cat request %s (parent %s) -> parent bad cat\n", app -> title_en ? app -> title_en : "no name?", catname, parentcatname ? parentcatname : "n/a" );
+      pnd_log ( pndn_warning, "PXML Fail %s: Cat request %s (parent %s) -> parent bad cat\n", app -> title_en ? app -> title_en : "no name?", catname, parentcatname ? parentcatname : "n/a" );
       // fix immediately so code doesn't explode
       parentcatname = NULL;
     } else {
@@ -395,12 +401,12 @@ unsigned char category_meta_push ( char *catname, char *parentcatname, pnd_disco
     if ( fdcat -> parent_cat == NULL ) {
       // but wait, catname is actually a parent cat...
       cat_is_clean = 0;
-      printf ( "PXML Fail %s: Cat request %s (parent %s) -> cat wants to be child, but FD says its a parent\n", app -> title_en ? app -> title_en : "no name?", catname, parentcatname ? parentcatname : "n/a" );
+      pnd_log ( pndn_warning, "PXML Fail %s: Cat request %s (parent %s) -> cat wants to be child, but FD says its a parent\n", app -> title_en ? app -> title_en : "no name?", catname, parentcatname ? parentcatname : "n/a" );
     }
     if ( fdpcat -> parent_cat ) {
       // but wait, parent cat is actually a subcat!
       cat_is_clean = 0;
-      printf ( "PXML Fail %s: Cat request %s (parent %s) -> parent cat, FD says its a child\n", app -> title_en ? app -> title_en : "no name?", catname, parentcatname ? parentcatname : "n/a" );
+      pnd_log ( pndn_warning, "PXML Fail %s: Cat request %s (parent %s) -> parent cat, FD says its a child\n", app -> title_en ? app -> title_en : "no name?", catname, parentcatname ? parentcatname : "n/a" );
     }
 
   } else {
@@ -409,7 +415,7 @@ unsigned char category_meta_push ( char *catname, char *parentcatname, pnd_disco
     if ( fdcat -> parent_cat ) {
       // but wait, cat actually has a parent!
       cat_is_clean = 0;
-      printf ( "PXML Fail %s: Cat request %s (parent %s) -> cat wants to be parent, FD says its a child\n", app -> title_en ? app -> title_en : "no name?", catname, parentcatname ? parentcatname : "n/a" );
+      pnd_log ( pndn_warning, "PXML Fail %s: Cat request %s (parent %s) -> cat wants to be parent, FD says its a child\n", app -> title_en ? app -> title_en : "no name?", catname, parentcatname ? parentcatname : "n/a" );
     }
 
   }
@@ -421,11 +427,11 @@ unsigned char category_meta_push ( char *catname, char *parentcatname, pnd_disco
     { 
       // child cat points to a different parent than requested parent!
       cat_is_clean = 0;
-      printf ( "PXML Fail %s: Cat request %s (parent %s) -> cat wants to be child of a cat which FD says is the wrong parent (1)\n", app -> title_en ? app -> title_en : "no name?", catname, parentcatname ? parentcatname : "n/a" );
+      pnd_log ( pndn_warning, "PXML Fail %s: Cat request %s (parent %s) -> cat wants to be child of a cat which FD says is the wrong parent (1)\n", app -> title_en ? app -> title_en : "no name?", catname, parentcatname ? parentcatname : "n/a" );
     } else if ( strcasecmp ( fdcat -> parent_cat, fdpcat -> cat ) != 0 ) {
       // child cat points to a different parent than requested parent!
       cat_is_clean = 0;
-      printf ( "PXML Fail %s: Cat request %s (parent %s) -> cat wants to be child of a cat which FD says is the wrong parent (2)\n", app -> title_en ? app -> title_en : "no name?", catname, parentcatname ? parentcatname : "n/a" );
+      pnd_log ( pndn_warning, "PXML Fail %s: Cat request %s (parent %s) -> cat wants to be child of a cat which FD says is the wrong parent (2)\n", app -> title_en ? app -> title_en : "no name?", catname, parentcatname ? parentcatname : "n/a" );
     }
   }
 
@@ -435,7 +441,7 @@ unsigned char category_meta_push ( char *catname, char *parentcatname, pnd_disco
     // set Other visibility
     visiblep = cat_is_visible ( g_conf, BADCATNAME );
     // fix cat request
-    fdcat = freedesktop_category_query ( BADCATNAME );
+    fdcat = freedesktop_category_query ( BADCATNAME, NULL );
     catname = fdcat -> cat;
     // nullify parent cat request (if any)
     fdpcat = NULL;
@@ -522,8 +528,8 @@ unsigned char category_meta_push ( char *catname, char *parentcatname, pnd_disco
 
   // is app already in the target cat? (ie: its being pushed twice due to cat mapping or Other'ing or something..)
   if ( app ) {
-    if ( category_contains_app ( catname, app -> unique_id ) ) {
-      printf ( "App Fail: app (%s %s) is already in cat %s\n", app -> title_en ? app -> title_en : "no name?", app -> unique_id, catname );
+    if ( category_contains_app ( catname, parentcatname, app -> unique_id ) ) {
+      pnd_log ( pndn_warning, "App Fail: app (%s %s) is already in cat %s\n", app -> title_en ? app -> title_en : "no name?", app -> unique_id, catname );
       return ( 1 ); // success, already there!
     }
   }
@@ -533,8 +539,9 @@ unsigned char category_meta_push ( char *catname, char *parentcatname, pnd_disco
   // so, is the cat we're looking at right now the apps main (or main alt) cat?
   if ( parentp ) {
     // and does this app have sub/altsub cats?
-    if ( app -> main_category1 || app -> main_category2 ||
-        app -> alt_category1 || app -> alt_category2 )
+    if ( ( parentp == 1 && ( app -> main_category1 || app -> main_category2 ) ) ||
+        ( parentp == 2 && ( app -> alt_category1 || app -> alt_category2 ) )
+       )
     {
       // and we're only desiring the subcat version of the app?
       if ( pnd_conf_get_as_int_d ( g_conf, "tabs.subcat_to_parent", 1 ) == 0 ) {
@@ -561,7 +568,7 @@ unsigned char category_meta_push ( char *catname, char *parentcatname, pnd_disco
     // iv) create the dummy app folder by pushing the disco into the apprefs as normal
     // v) create a dummy '..' for going back up, in the child
 
-    mm_category_t *pcat = pnd_box_find_by_key ( m_categories, parentcatname );
+    mm_category_t *pcat = pnd_box_find_by_key ( m_categories, _normalize ( parentcatname, NULL ) );
 
     if ( ! pcat -> disco ) {
       pcat -> disco = pnd_box_new ( pcat -> catname );
@@ -589,7 +596,7 @@ unsigned char category_meta_push ( char *catname, char *parentcatname, pnd_disco
        }
        disco -> object_flags = PND_DISCO_GENERATED;
        disco -> object_type = pnd_object_type_directory; // suggest to Grid that its a dir
-       disco -> object_path = strdup ( catname );
+       disco -> object_path = strdup ( _normalize ( catname, parentcatname ) );
 
        category_push ( parentcatname, NULL /* parent cat */, disco, 0 /*ovrh*/, NULL /* fspath */, 1 /* visible */ );
 
@@ -779,7 +786,11 @@ void category_publish ( unsigned int filter_mask, char *param ) {
     if ( filter_mask == CFALL ) {
       interested = 1;
     } else if ( filter_mask == CFBYNAME ) {
-      if ( strcasecmp ( iter -> catname, param ) == 0 ) {
+      char *foo = strchr ( param, '*' ) + 1;
+      if ( strncasecmp ( iter -> catname, param, strlen ( iter -> catname ) ) == 0 &&
+          iter -> parent_catname &&
+          strcasecmp ( iter -> parent_catname, foo ) == 0 )
+      {
        interested = 1;
       }
     } else if ( iter -> catflags == filter_mask ) {
@@ -854,9 +865,9 @@ int category_index ( char *catname ) {
   return ( -1 );
 }
 
-unsigned char category_contains_app ( char *catname, char *unique_id ) {
+unsigned char category_contains_app ( char *catname, char *parentcatname, char *unique_id ) {
 
-  mm_category_t *c = pnd_box_find_by_key ( m_categories, catname );
+  mm_category_t *c = pnd_box_find_by_key ( m_categories, _normalize ( catname, parentcatname ) );
 
   if ( ! c ) {
     return ( 0 ); // wtf?