Code

screen_search: fix crash when disconnected
[ncmpc.git] / src / strfsong.c
index 3d5abd5797dfd78e50e9515f72763efabf5ee7cc..35086e85de41afe083d2f43e71f58ebd7453f7a9 100644 (file)
@@ -118,8 +118,12 @@ _strfsong(gchar *s,
        gchar *temp;
        gsize n, length = 0;
        gboolean found = FALSE;
+       /* "missed" helps handling the case of mere literal text like
+          found==TRUE instead of found==FALSE. */
+       gboolean missed = FALSE;
+
+       s[0] = '\0';
 
-       memset(s, 0, max);
        if (song == NULL)
                return 0;
 
@@ -127,9 +131,10 @@ _strfsong(gchar *s,
                /* OR */
                if (p[0] == '|') {
                        ++p;
-                       if(!found) {
-                               memset(s, 0, max);
+                       if(missed && !found) {
+                               s[0] = '\0';
                                length = 0;
+                               missed = FALSE;
                        } else {
                                p = skip(p);
                        }
@@ -139,10 +144,11 @@ _strfsong(gchar *s,
                /* AND */
                if (p[0] == '&') {
                        ++p;
-                       if(!found) {
+                       if(missed && !found) {
                                p = skip(p);
                        } else {
                                found = FALSE;
+                               missed = FALSE;
                        }
                        continue;
                }
@@ -154,6 +160,8 @@ _strfsong(gchar *s,
                                g_strlcat(s, temp, max);
                                length = strlen(s);
                                found = TRUE;
+                       } else {
+                               missed = TRUE;
                        }
                        g_free(temp);
                        continue;
@@ -162,8 +170,8 @@ _strfsong(gchar *s,
                /* EXPRESSION END */
                if (p[0] == ']') {
                        if(last) *last = p+1;
-                       if(!found && length) {
-                               memset(s, 0, max);
+                       if(missed && !found && length) {
+                               s[0] = '\0';
                                length = 0;
                        }
                        return length;
@@ -172,6 +180,7 @@ _strfsong(gchar *s,
                /* pass-through non-escaped portions of the format string */
                if (p[0] != '#' && p[0] != '%' && length<max) {
                        s[length++] = *p;
+                       s[length] = '\0';
                        p++;
                        continue;
                }
@@ -179,6 +188,7 @@ _strfsong(gchar *s,
                /* let the escape character escape itself */
                if (p[0] == '#' && p[1] != '\0' && length<max) {
                        s[length++] = *(p+1);
+                       s[length] = '\0';
                        p+=2;
                        continue;
                }
@@ -243,12 +253,14 @@ _strfsong(gchar *s,
                if( temp == NULL) {
                        gsize templen=n;
                        /* just pass-through any unknown specifiers (including esc) */
-                       /* drop a null char in so printf stops at the end of this specifier,
-                          but put the real character back in (pseudo-const) */
                        if( length+templen > max )
                                templen = max-length;
-                       g_strlcat(s, p,max);
+                       gchar *ident = g_strndup(p, templen);
+                       g_strlcat(s, ident, max);
                        length+=templen;
+                       g_free(ident);
+
+                       missed = TRUE;
                } else {
                        gsize templen = strlen(temp);