This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch tymux
in repository terminology.

View the commit online.

commit d23f3599d6eca48365aa89bf4de198f5542bd7be
Author: [email protected] <[email protected]>
AuthorDate: Mon Mar 16 15:45:57 2026 -0600

    fix: initialize and cleanup shadow Termpty correctly in tymux mode
    
    The shadow pty was under-initialized, causing valgrind errors and
    potential crashes when cells with hyperlinks were rendered. Initialize
    the hyperlink bitmap and links array (65536 slots) to match termpty_new,
    add proper config pointer and wrap mode, and implement complete cleanup
    in _shadow_pty_free to free all allocated resources.
    
    - _shadow_pty_new: accept Config pointer; allocate hl.bitmap and
      hl.links (full HL_LINKS_MAX entries pre-allocated to prevent NULL
      deref); set termstate.wrap=1; remove dead write_cb assignment
    - _shadow_pty_free: cleanup prop.title, prop.icon, prop.user_title,
      hl.links (with term_link_free loop), hl.bitmap, tabs, back, buf,
      write_buffer to match termpty_free
    - termsession_attach: pass Config to shadow pty
    - termio: guard termpty_config_update for session-mode ptys; pass
      config to termsession_attach
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
---
 src/bin/termio.c      | 11 ++++++++--
 src/bin/termsession.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++----
 src/bin/termsession.h |  2 ++
 3 files changed, 67 insertions(+), 6 deletions(-)

diff --git a/src/bin/termio.c b/src/bin/termio.c
index 69102ef5..ab3292ca 100644
--- a/src/bin/termio.c
+++ b/src/bin/termio.c
@@ -541,7 +541,14 @@ termio_config_update(Evas_Object *obj)
    sd->jump_on_change = sd->config->jump_on_change;
    sd->jump_on_keypress = sd->config->jump_on_keypress;
 
-   termpty_config_update(sd->pty, sd->config);
+#ifdef HAVE_TYMUX
+   /* Shadow pty has no real PTY and no scrollback; only update the config
+    * pointer so rendering picks up colour/font state changes. */
+   if (sd->session)
+     sd->pty->config = sd->config;
+   else
+#endif
+     termpty_config_update(sd->pty, sd->config);
    sd->scroll = 0;
 
    colors_term_init(sd->grid.obj, sd->config->color_scheme);
@@ -4322,7 +4329,7 @@ termio_add(Evas_Object *win, Config *config,
      {
         sd->session_name = eina_stringshare_add(session_name);
         Termpty *spty = NULL;
-        sd->session = termsession_attach(session_name, w, h, &spty);
+        sd->session = termsession_attach(session_name, w, h, config, &spty);
         if (!sd->session)
           {
              ERR("Could not attach to tymux session '%s'", session_name);
diff --git a/src/bin/termsession.c b/src/bin/termsession.c
index 9235c645..72d8fa05 100644
--- a/src/bin/termsession.c
+++ b/src/bin/termsession.c
@@ -38,7 +38,7 @@ _session_write_cb(const char *buf, int len, void *data)
 /* ── shadow Termpty ─────────────────────────────────────────────────── */
 
 static Termpty *
-_shadow_pty_new(TermSession *ts, int cols, int rows)
+_shadow_pty_new(TermSession *ts, int cols, int rows, Config *config)
 {
    Termpty *ty;
 
@@ -51,6 +51,10 @@ _shadow_pty_new(TermSession *ts, int cols, int rows)
    ty->pid     = -1;
    ty->w       = cols;
    ty->h       = rows;
+   ty->config  = config;
+
+   /* wrap=1 is the correct out-of-the-box terminal default */
+   ty->termstate.wrap = 1;
 
    ty->screen = calloc((size_t)(cols * rows), sizeof(Termcell));
    if (!ty->screen)
@@ -67,8 +71,35 @@ _shadow_pty_new(TermSession *ts, int cols, int rows)
         return NULL;
      }
 
-   ty->write_cb.func = _session_write_cb;
-   ty->write_cb.data = ""
+   /* hl.bitmap: allocate to prevent NULL-deref if any hyperlink escape
+    * or rendering path checks it.  Mark slot 0 used, same as termpty_new. */
+   ty->hl.bitmap = calloc(1, HL_LINKS_MAX / 8);
+   if (!ty->hl.bitmap)
+     {
+        free(ty->screen2);
+        free(ty->screen);
+        free(ty);
+        return NULL;
+     }
+   ty->hl.bitmap[0] = 1;
+
+   /* hl.links: allocate the full HL_LINKS_MAX entries (zero-initialised) so
+    * that any link_id received from the daemon can be safely dereferenced by
+    * termio and termpty.h inline helpers without bounds checks.  hl.size is
+    * set to match, mirroring the bitmap coverage. */
+   ty->hl.links = calloc(HL_LINKS_MAX, sizeof(Term_Link));
+   if (!ty->hl.links)
+     {
+        free(ty->hl.bitmap);
+        free(ty->screen2);
+        free(ty->screen);
+        free(ty);
+        return NULL;
+     }
+   ty->hl.size = HL_LINKS_MAX;
+
+   /* write_cb is intentionally left unset here; the caller (termsession_attach)
+    * wires it once the TermSession is fully constructed. */
 
    return ty;
 }
@@ -78,8 +109,28 @@ _shadow_pty_free(Termpty *ty)
 {
    if (!ty)
      return;
+   eina_stringshare_del(ty->prop.title);
+   eina_stringshare_del(ty->prop.user_title);
+   eina_stringshare_del(ty->prop.icon);
    free(ty->screen);
    free(ty->screen2);
+   if (ty->hl.links)
+     {
+        uint16_t i;
+
+        for (i = 0; i < ty->hl.size; i++)
+          {
+             Term_Link *l = ty->hl.links + i;
+
+             term_link_free(ty, l);
+          }
+        free(ty->hl.links);
+     }
+   free(ty->hl.bitmap);
+   free(ty->buf);
+   ty_sb_free(&ty->write_buffer);
+   free(ty->tabs);
+   free(ty->back);
    free(ty);
 }
 
@@ -277,6 +328,7 @@ _ensure_daemon(const char *session_name, const char *sock_path)
 TermSession *
 termsession_attach(const char *session_name,
                    int cols, int rows,
+                   Config *config,
                    Termpty **shadow_pty_out)
 {
    char              sock_path[256];
@@ -370,7 +422,7 @@ termsession_attach(const char *session_name,
 
    /* Use requested cols/rows for the shadow pty; _sync_shadow will
     * adjust to whatever the server reports in the header. */
-   ty = _shadow_pty_new(NULL, cols, rows);
+   ty = _shadow_pty_new(NULL, cols, rows, config);
    if (!ty)
      {
         ERR("termsession: failed to allocate shadow pty");
diff --git a/src/bin/termsession.h b/src/bin/termsession.h
index 1df9148e..a6af826d 100644
--- a/src/bin/termsession.h
+++ b/src/bin/termsession.h
@@ -8,6 +8,7 @@
 #include <Eina.h>
 #include <Ecore.h>
 #include <Ecore_Evas_Types.h>
+#include "config.h"
 #include "termpty.h"
 #include "termsrv.h"
 
@@ -39,6 +40,7 @@ struct _TermSession {
  */
 TermSession *termsession_attach(const char *session_name,
                                 int cols, int rows,
+                                Config *config,
                                 Termpty **shadow_pty_out);
 
 /* Send DETACH, munmap, close socket, free shadow Termpty. */

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to