Skip to content

Commit

Permalink
Permit eudev to work with rules which include escaped double-quotes
Browse files Browse the repository at this point in the history
- Adjust parsing function to understand escaped double-quotes in rules.
- Added new test to udev-test.pl to confirm escaped quotes work.
- Bring eudev up to date with systemd pull request $6890.

This commit resolves GitHub issue #187.

This is a slightly adjusted patch/commit from systemd's udev.
Original upstream commit: 8a247d50abb5315adcc64daea10bc836c9d4c6e0
Provided by Franck Bui (GitHub user fbuihuu)
  • Loading branch information
Jesse Smith committed Oct 6, 2021
1 parent 74e8d28 commit d16f9d5
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 9 deletions.
8 changes: 5 additions & 3 deletions src/udev/udev-event.c
Original file line number Diff line number Diff line change
Expand Up @@ -682,10 +682,12 @@ int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[]) {

pos = cmd;
while (pos != NULL && pos[0] != '\0') {
if (pos[0] == '\'') {
/* do not separate quotes */
if (IN_SET(pos[0], '\'', '"')) {
/* do not separate quotes or double quotes */
char delim[2] = { pos[0], '\0' };

pos++;
argv[i] = strsep(&pos, "\'");
argv[i] = strsep(&pos, delim);
if (pos != NULL)
while (pos[0] == ' ')
pos++;
Expand Down
24 changes: 18 additions & 6 deletions src/udev/udev-rules.c
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,7 @@ static int attr_subst_subdir(char *attr, size_t len) {
static int get_key(struct udev *udev, char **line, char **key, enum operation_type *op, char **value) {
char *linepos;
char *temp;
unsigned i, j;

linepos = *line;
if (linepos == NULL || linepos[0] == '\0')
Expand Down Expand Up @@ -835,14 +836,25 @@ static int get_key(struct udev *udev, char **line, char **key, enum operation_ty
*value = linepos;

/* terminate */
temp = strchr(linepos, '"');
if (!temp)
return -1;
temp[0] = '\0';
temp++;
for (i = 0, j = 0; ; i++, j++) {

if (linepos[i] == '"')
break;

if (linepos[i] == '\0')
return -1;

/* double quotes can be escaped */
if (linepos[i] == '\\')
if (linepos[i+1] == '"')
i++;

linepos[j] = linepos[i];
}
linepos[j] = '\0';

/* move line to next key */
*line = temp;
*line = linepos + i + 1;
return 0;
}

Expand Down
24 changes: 24 additions & 0 deletions test/udev-test.pl
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,30 @@
exp_name => "foo7" ,
rules => <<EOF
SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n 'foo3 foo4' 'foo5 foo6 foo7 foo8'", KERNEL=="sda5", SYMLINK+="%c{5}"
EOF
},
{
desc => "program arguments combined with escaped double quotes, part 1",
devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
exp_name => "foo2" ,
rules => <<EOF
SUBSYSTEMS=="scsi", PROGRAM=="/bin/sh -c 'printf %%s \\\"foo1 foo2\\\" | grep \\\"foo1 foo2\\\"'", KERNEL=="sda5", SYMLINK+="%c{2}"
EOF
},
{
desc => "program arguments combined with escaped double quotes, part 2",
devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
exp_name => "foo2" ,
rules => <<EOF
SUBSYSTEMS=="scsi", PROGRAM=="/bin/sh -c \\\"printf %%s 'foo1 foo2' | grep 'foo1 foo2'\\\"", KERNEL=="sda5", SYMLINK+="%c{2}"
EOF
},
{
desc => "program arguments combined with escaped double quotes, part 3",
devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5",
exp_name => "foo2" ,
rules => <<EOF
SUBSYSTEMS=="scsi", PROGRAM=="/bin/sh -c 'printf \\\"%%s %%s\\\" \\\"foo1 foo2\\\" \\\"foo3\\\"| grep \\\"foo1 foo2\\\"'", KERNEL=="sda5", SYMLINK+="%c{2}"
EOF
},
{
Expand Down

0 comments on commit d16f9d5

Please sign in to comment.