Skip to content

Commit

Permalink
expand: portably tokenise string using strsep
Browse files Browse the repository at this point in the history
Rather than using sscanf() to try and split a string up to a known
delimiter (period) which is not valid whitespace, instead use strsep()
to tokenise the string and match on the constituent parts.

This should avoid segfaults across platforms.

Fixes #101
  • Loading branch information
ThomasAdam committed May 27, 2020
1 parent 9b0570e commit b278634
Showing 1 changed file with 39 additions and 37 deletions.
76 changes: 39 additions & 37 deletions fvwm/expand.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "libs/Parse.h"
#include "libs/Strings.h"
#include "libs/ColorUtils.h"
#include "libs/safemalloc.h"
#include "fvwm.h"
#include "externs.h"
#include "cursor.h"
Expand Down Expand Up @@ -483,56 +484,57 @@ static signed int expand_vars_extended(
}

/* We could be left with "<NAME>.?" */
char *m_name = NULL;
struct monitor *mon;
char *m_name = NULL;
struct monitor *mon;
char *rest_s;

/* The first word is the monitor name:
*
* monitor.Virtual-1
*
* so scan for the first full-stop.
*/
if (sscanf(rest, "%[^.].", m_name) < 1)
return -1;

mon = monitor_by_name(m_name);
if (m_name == NULL)
return -1;
if (strcmp(mon->si->name, m_name) == 1)
return -1;
rest_s = fxstrdup(rest);
while ((m_name = strsep(&rest_s, ".")) != NULL) {
mon = monitor_by_name(m_name);
if (m_name == NULL)
return -1;
if (strcmp(mon->si->name, m_name) == 1)
return -1;

/* Skip over the monitor name. */
rest += strlen(m_name) + 1;
/* Skip over the monitor name. */
rest += strlen(m_name) + 1;

/* Match remainder to valid fields. */
if (strcmp(rest, "x") == 0) {
is_numeric = True;
val = mon->si->x;
goto GOT_STRING;
}
/* Match remainder to valid fields. */
if (strcmp(rest, "x") == 0) {
is_numeric = True;
val = mon->si->x;
goto GOT_STRING;
}

if (strcmp(rest, "y") == 0) {
is_numeric = True;
val = mon->si->y;
goto GOT_STRING;
}
if (strcmp(rest, "y") == 0) {
is_numeric = True;
val = mon->si->y;
goto GOT_STRING;
}

if (strcmp(rest, "width") == 0) {
is_numeric = True;
val = mon->si->w;
goto GOT_STRING;
}
if (strcmp(rest, "width") == 0) {
is_numeric = True;
val = mon->si->w;
goto GOT_STRING;
}

if (strcmp(rest, "height") == 0) {
is_numeric = True;
val = mon->si->h;
goto GOT_STRING;
}
if (strcmp(rest, "height") == 0) {
is_numeric = True;
val = mon->si->h;
goto GOT_STRING;
}

if (strcmp(rest, "output") == 0) {
is_numeric = True;
val = (int)m->si->rr_output;
goto GOT_STRING;
if (strcmp(rest, "output") == 0) {
is_numeric = True;
val = (int)m->si->rr_output;
goto GOT_STRING;
}
}
break;
}
Expand Down

0 comments on commit b278634

Please sign in to comment.