Skip to content

fix an off by one error in token get #4105

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
8.15.4

- fix an off-by-one error in vips__token_get()

11/8/24 8.15.3

- fix dzsave of >8-bit images to JPEG
Expand Down
66 changes: 33 additions & 33 deletions libvips/iofuncs/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -1241,7 +1241,11 @@ vips__token_get(const char *p, VipsToken *token, char *string, int size)
const char *q;
int ch;
int n;
int i;

/* string return defaults to "".
*/
if (size > 0)
string[0] = '\0';

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

case '"':
case '\'':
/* Parse a quoted string. Copy up to ", interpret any \",
* error if no closing ".
/* Parse a quoted string. Copy up to " or end of string, interpret
* any \",
*/
*token = VIPS_TOKEN_STRING;

do {
/* Number of characters until the next quote
* character or end of string.
/* Move q to the next matching quote, or the end of the string.
*/
if ((q = strchr(p + 1, ch)))
n = q - p + 1;
else
n = strlen(p + 1);
if (!(q = strchr(p + 1, ch)))
q = p + strlen(p);

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

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

string += i;
size -= i;
p += n + 1;
string += n;
size -= n;
p = q;
} while (p[0] && p[-1] == '\\');

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

break;

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

i = VIPS_MIN(q - p, size);
vips_strncpy(string, p, i + 1);
n = VIPS_MIN(q - p, size);
vips_strncpy(string, p, n + 1);
p = q;

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

break;
Expand Down
Loading