diff --git a/ChangeLog b/ChangeLog index 17c215a6..80726766 100644 --- a/ChangeLog +++ b/ChangeLog @@ -67,6 +67,7 @@ - remove outchecks from documented API - support gobject-introspection - new Python binding based on gobject-introspection +- only spot options at the end of arg strings 12/10/11 started 7.26.6 - NOCACHE was not being set correctly on OS X causing performance diff --git a/TODO b/TODO index 75258676..980b7282 100644 --- a/TODO +++ b/TODO @@ -9,12 +9,6 @@ - add __add__ etc overloads -- vips__token_get() will assert(0) if a string token is too large ... it - should return an error or silently truncate - - - - @@ -24,14 +18,9 @@ + - foreign docs come up as "VipsForeignSave", annoying, why? -- we can no longer have round brackets in filenames, argh, maybe only allow - []{} to enclose args - -- add something to parse option sets backwards, so only trailing {}()[] are - seen - diff --git a/libvips/iofuncs/object.c b/libvips/iofuncs/object.c index 1856116e..1c89a5be 100644 --- a/libvips/iofuncs/object.c +++ b/libvips/iofuncs/object.c @@ -285,13 +285,6 @@ vips_argument_instance_free( VipsArgumentInstance *argument_instance ) g_free( argument_instance ); } -/** - * vips__argument_table_lookup: (skip) - * @table: table to search - * @pspec: spec to search for - * - * Find the #VipsArgument for a @pspec. - */ VipsArgument * vips__argument_table_lookup( VipsArgumentTable *table, GParamSpec *pspec ) { diff --git a/libvips/iofuncs/util.c b/libvips/iofuncs/util.c index ffea6d47..1747a232 100644 --- a/libvips/iofuncs/util.c +++ b/libvips/iofuncs/util.c @@ -270,6 +270,8 @@ vips_hash_table_map( GHashTable *hash, VipsSListMap2Fn fn, void *a, void *b ) } /* Like strncpy(), but always NULL-terminate, and don't pad with NULLs. + * If @n is 100 and @src is more than 99 characters, 99 are copied and the + * final byte of @dest is set to '\0'. */ char * vips_strncpy( char *dest, const char *src, int n ) @@ -1166,10 +1168,13 @@ vips_popenf( const char *fmt, const char *mode, ... ) return( fp ); } -/* Break a command-line argument into tokens separated by whitespace. Strings - * can't be adjacent, so "hello world" (without quotes) is a single string. - * Strings are written (with \" escaped) into @string, which must be @size - * characters large. NULL for end of tokens. +/* Break a command-line argument into tokens separated by whitespace. + * + * Strings can't be adjacent, so "hello world" (without quotes) is a single + * string. Strings are written (with \" escaped) into @string. If the string + * is larger than @size, it is silently null-termionated and truncated. + * + * Return NULL for end of tokens. */ const char * vips__token_get( const char *p, VipsToken *token, char *string, int size ) @@ -1177,6 +1182,7 @@ vips__token_get( const char *p, VipsToken *token, char *string, int size ) const char *q; int ch; int n; + int i; /* Parse this token with p. */ @@ -1232,19 +1238,20 @@ vips__token_get( const char *p, VipsToken *token, char *string, int size ) else n = strlen( p + 1 ); - g_assert( size > n + 1 ); - memcpy( string, p + 1, n ); - string[n] = '\0'; - - /* p[n + 1] might not be " if there's no closing ". + /* How much can we copy to the buffer? */ - if( p[n + 1] == ch && p[n] == '\\' ) - /* An escaped ": overwrite the '\' with '"' - */ - string[n - 1] = ch; + i = VIPS_MIN( n, size ); + vips_strncpy( string, p + 1, i ); - string += n; - size -= n; + /* We might have stopped at an escaped quote. If the + * string was not truncated, swap the preceding + * backslash for a quote. + */ + if( p[n + 1] == ch && p[n] == '\\' && i == n ) + string[i - 1] = ch; + + string += i; + size -= i; p += n + 1; } while( p[0] && p[-1] == '\\' ); @@ -1259,18 +1266,19 @@ vips__token_get( const char *p, VipsToken *token, char *string, int size ) */ *token = VIPS_TOKEN_STRING; n = strcspn( p, "<[{()}]>=," ); - g_assert( size > n + 1 ); - memcpy( string, p, n ); - string[n] = '\0'; + i = VIPS_MIN( n, size ); + vips_strncpy( string, p, i ); p += n; /* We remove leading whitespace, so we trim trailing - * whitespace from unquoted strings too. + * whitespace from unquoted strings too. Only if the string + * hasn't been truncated. */ - while( isspace( string[n - 1] ) ) { - string[n - 1] = '\0'; - n -= 1; - } + if( i == n ) + while( i > 0 && isspace( string[i - 1] ) ) { + string[i - 1] = '\0'; + i--; + } break; }