Skip to content

Commit 99b3d18

Browse files
authored
fix an off by one error in token get (#4105)
* fix an off by one error in token get * add tests for tokenisation * style * empty default string return * move tests to master
1 parent 1a86d4e commit 99b3d18

File tree

2 files changed

+37
-33
lines changed

2 files changed

+37
-33
lines changed

ChangeLog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
8.15.4
2+
3+
- fix an off-by-one error in vips__token_get()
4+
15
11/8/24 8.15.3
26

37
- fix dzsave of >8-bit images to JPEG

libvips/iofuncs/util.c

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,7 +1241,11 @@ vips__token_get(const char *p, VipsToken *token, char *string, int size)
12411241
const char *q;
12421242
int ch;
12431243
int n;
1244-
int i;
1244+
1245+
/* string return defaults to "".
1246+
*/
1247+
if (size > 0)
1248+
string[0] = '\0';
12451249

12461250
/* Parse this token with p.
12471251
*/
@@ -1277,61 +1281,57 @@ vips__token_get(const char *p, VipsToken *token, char *string, int size)
12771281

12781282
case '"':
12791283
case '\'':
1280-
/* Parse a quoted string. Copy up to ", interpret any \",
1281-
* error if no closing ".
1284+
/* Parse a quoted string. Copy up to " or end of string, interpret
1285+
* any \",
12821286
*/
12831287
*token = VIPS_TOKEN_STRING;
12841288

12851289
do {
1286-
/* Number of characters until the next quote
1287-
* character or end of string.
1290+
/* Move q to the next matching quote, or the end of the string.
12881291
*/
1289-
if ((q = strchr(p + 1, ch)))
1290-
n = q - p + 1;
1291-
else
1292-
n = strlen(p + 1);
1292+
if (!(q = strchr(p + 1, ch)))
1293+
q = p + strlen(p);
12931294

1294-
/* How much can we copy to the buffer?
1295-
*/
1296-
i = VIPS_MIN(n, size);
1297-
vips_strncpy(string, p + 1, i);
1295+
// number of characters we copy to the output
1296+
n = VIPS_MIN(q - p - 1, size - 1);
1297+
vips_strncpy(string, p + 1, n + 1);
12981298

12991299
/* We might have stopped at an escaped quote. If the
1300-
* string was not truncated, swap the preceding
1301-
* backslash for a quote.
1300+
* char before the end is a backslash, swap it for a quote.
13021301
*/
1303-
if (p[n + 1] == ch && p[n] == '\\' && i == n)
1304-
string[i - 1] = ch;
1302+
if (q[-1] == '\\')
1303+
string[n - 1] = ch;
13051304

1306-
string += i;
1307-
size -= i;
1308-
p += n + 1;
1305+
string += n;
1306+
size -= n;
1307+
p = q;
13091308
} while (p[0] && p[-1] == '\\');
13101309

1311-
p += 1;
1310+
// step over the terminating quote, if we hit one
1311+
if (p[0] == ch)
1312+
p += 1;
13121313

13131314
break;
13141315

13151316
default:
1316-
/* It's an unquoted string: read up to the next non-string
1317-
* character. We don't allow two strings next to each other,
1318-
* so the next break must be brackets, equals, comma.
1317+
/* It's an unquoted string: read up to the next non-string character.
1318+
* We don't allow two strings next to each other, so the next break
1319+
* must be brackets, equals, comma.
13191320
*/
13201321
*token = VIPS_TOKEN_STRING;
13211322
q = p + strcspn(p, "[]=,");
13221323

1323-
i = VIPS_MIN(q - p, size);
1324-
vips_strncpy(string, p, i + 1);
1324+
n = VIPS_MIN(q - p, size);
1325+
vips_strncpy(string, p, n + 1);
13251326
p = q;
13261327

1327-
/* We remove leading whitespace, so we trim trailing
1328-
* whitespace from unquoted strings too. Only if the string
1329-
* hasn't been truncated.
1328+
/* We remove leading whitespace, so we trim trailing whitespace from
1329+
* unquoted strings too. Only if the string hasn't been truncated.
13301330
*/
1331-
if (i != size)
1332-
while (i > 0 && isspace(string[i - 1])) {
1333-
string[i - 1] = '\0';
1334-
i--;
1331+
if (n != size)
1332+
while (n > 0 && isspace(string[n - 1])) {
1333+
string[n - 1] = '\0';
1334+
n--;
13351335
}
13361336

13371337
break;

0 commit comments

Comments
 (0)