Protect against overly long savepoint names
authorDan Scott <dscott@laurentian.ca>
Fri, 11 Jan 2013 06:32:13 +0000 (01:32 -0500)
committerBill Erickson <berick@esilibrary.com>
Wed, 16 Jan 2013 20:00:58 +0000 (15:00 -0500)
Per http://postgresql.org/docs/9.1/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS,
the maximum identifier length works out to being 63 bytes (+1 for the
null terminator), so to avoid potential memory pressure by a 10GB string
somehow being passed in as the savepoint name, malloc no more than 64
bytes and copy no more than 63 bytes from the incoming name to the
escaped name.

Signed-off-by: Dan Scott <dscott@laurentian.ca>
Signed-off-by: Galen Charlton <gmc@esilibrary.com>
Open-ILS/src/c-apps/oils_sql.c

index 08a390b..d27c272 100644 (file)
@@ -7288,11 +7288,25 @@ int writeAuditInfo( osrfMethodContext* ctx, const char* user_id, const char* ws_
 static char* _sanitize_savepoint_name( const char* sp ) {
 
        const char* safe_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345789_";
-       char* safeSpName = safe_malloc( strlen( sp ) + 1);
+
+       // PostgreSQL uses NAMEDATALEN-1 as a max length for identifiers,
+       // and the default value of NAMEDATALEN is 64; that should be long enough
+       // for our purposes, and it's unlikely that anyone is going to recompile
+       // PostgreSQL to have a smaller value, so cap the identifier name
+       // accordingly to avoid the remote chance that someone manages to pass in a
+       // 12GB savepoint name
+       const int MAX_LITERAL_NAMELEN = 63;
+       int len = 0;
+       len = strlen( sp );
+       if (len > MAX_LITERAL_NAMELEN) {
+               len = MAX_LITERAL_NAMELEN;
+       }
+
+       char* safeSpName = safe_malloc( len + 1 );
        int i = 0;
        int j;
        char* found;
-       for (j = 0; j < strlen( sp ); j++) {
+       for (j = 0; j < len; j++) {
        found = strchr(safe_chars, sp[j]);
                if (found) {
                        safeSpName[ i++ ] = found[0];