CVE-2020-12135: Integer Overflow or Wraparound (CWE-190)
value: bson before 0.8 incorrectly uses int rather than size_t for many variables, parameters, and return values. In particular, the bson_ensure_space() parameter bytesNeeded could have an integer overflow via properly constructed bson input.
CWE description: The product performs a calculation that can
         produce an integer overflow or wraparound when the logic
         assumes that the resulting value will always be larger than
         the original value. This occurs when an integer value is
         incremented to a value that is too large to store in the
         associated representation. When this occurs, the value may
         become a very small or negative number.
CVSS v3 base score: 5.5
Published: 2020-04-24T01:15Z
Repository: https://github.com/10gen-archive/mongo-c-driver-legacy
Language: C
Files changed: src/bcon.c, src/bson.c, src/bson.h, src/encoding.c, src/encoding.h, src/env.c, src/env.h, src/gridfs.c, src/gridfs.h, src/mongo.c
Commit date: 2013-01-07 22:30:02 +0100
Commit message: don't mix up int and size_t (first pass to fix that)

Diff: diff --git a/src/bcon.c b/src/bcon.c
index 87803f9..8b2a2d7 100644
--- a/src/bcon.c
+++ b/src/bcon.c
@@ -170,11 +170,11 @@ static bcon_error_t bson_append_bcon_with_state(bson *b, const bcon *bc, bcon_st
     char *key = 0;
     char *typespec = 0;
     unsigned char doc_stack[DOC_STACK_SIZE];
     size_t doc_stack_pointer = 0;
     size_t array_index = 0;
-    unsigned int array_index_stack[ARRAY_INDEX_STACK_SIZE];
+    size_t array_index_stack[ARRAY_INDEX_STACK_SIZE];
     size_t array_index_stack_pointer = 0;
     char array_index_buffer[ARRAY_INDEX_BUFFER_SIZE]; /* max BSON size */
     int end_of_data;
     const bcon *bcp;
     for (end_of_data = 0, bcp = bc; ret == BCON_OK && !end_of_data; bcp++) {
diff --git a/src/bson.c b/src/bson.c
index ef68c4c..37c299b 100644
--- a/src/bson.c
+++ b/src/bson.c
@@ -104,11 +104,11 @@ MONGO_EXPORT int bson_size( const bson *b ) {
         return 0;
     bson_little_endian32( &i, b->data );
     return i;
 }
 
-MONGO_EXPORT int bson_buffer_size( const bson *b ) {
+MONGO_EXPORT size_t bson_buffer_size( const bson *b ) {
     return (b->cur - b->data + 1);
 }
 
 
 MONGO_EXPORT const char *bson_data( const bson *b ) {
@@ -304,11 +304,11 @@ MONGO_EXPORT bson_type bson_find( bson_iterator *it, const bson *obj, const char
 MONGO_EXPORT bson_bool_t bson_iterator_more( const bson_iterator *i ) {
     return *( i->cur );
 }
 
 MONGO_EXPORT bson_type bson_iterator_next( bson_iterator *i ) {
-    int ds;
+    size_t ds;
 
     if ( i->first ) {
         i->first = 0;
         return ( bson_type )( *i->cur );
     }
@@ -418,11 +418,11 @@ MONGO_EXPORT bson_oid_t *bson_iterator_oid( const bson_iterator *i ) {
 MONGO_EXPORT int bson_iterator_int( const bson_iterator *i ) {
     switch ( bson_iterator_type( i ) ) {
     case BSON_INT:
         return bson_iterator_int_raw( i );
     case BSON_LONG:
-        return bson_iterator_long_raw( i );
+        return ( int )bson_iterator_long_raw( i );
     case BSON_DOUBLE:
         return bson_iterator_double_raw( i );
     default:
         return 0;
     }
@@ -602,26 +602,31 @@ void bson_init_size( bson *b, int size ) {
 static void bson_append_byte( bson *b, char c ) {
     b->cur[0] = c;
     b->cur++;
 }
 
-static void bson_append( bson *b, const void *data, int len ) {
+static void bson_append( bson *b, const void *data, size_t len ) {
     memcpy( b->cur , data , len );
     b->cur += len;
 }
 
 static void bson_append32( bson *b, const void *data ) {
     bson_little_endian32( b->cur, data );
     b->cur += 4;
 }
 
+static void bson_append32_as_int( bson *b, int data ) {
+    bson_little_endian32( b->cur, &data );
+    b->cur += 4;
+}
+
 static void bson_append64( bson *b, const void *data ) {
     bson_little_endian64( b->cur, data );
     b->cur += 8;
 }
 
-int bson_ensure_space( bson *b, const int bytesNeeded ) {
+int bson_ensure_space( bson *b, const size_t bytesNeeded ) {
     int pos = b->cur - b->data;
     char *orig = b->data;
     int new_size;
 
     if ( pos + bytesNeeded <= b->dataSize )
@@ -655,11 +660,11 @@ MONGO_EXPORT int bson_finish( bson *b ) {
         return BSON_ERROR;
 
     if ( ! b->finished ) {
         if ( bson_ensure_space( b, 1 ) == BSON_ERROR ) return BSON_ERROR;
         bson_append_byte( b, 0 );
-        i = b->cur - b->data;
+        i = ( int )( b->cur - b->data );
         bson_little_endian32( b->data, &i );
         b->finished = 1;
     }
 
     return BSON_OK;
@@ -673,11 +678,11 @@ MONGO_EXPORT void bson_destroy( bson *b ) {
         b->cur = 0;
         b->finished = 1;
     }
 }
 
-static int bson_append_estart( bson *b, int type, const char *name, const int dataSize ) {
+static int bson_append_estart( bson *b, int type, const char *name, const size_t dataSize ) {
     const int len = strlen( name ) + 1;
 
     if ( b->finished ) {
         b->err |= BSON_ALREADY_FINISHED;
         return BSON_ERROR;
@@ -740,19 +745,19 @@ MONGO_EXPORT int bson_append_undefined( bson *b, const char *name ) {
         return BSON_ERROR;
     return BSON_OK;
 }
 
 static int bson_append_string_base( bson *b, const char *name,
-                                    const char *value, int len, bson_type type ) {
+                                    const char *value, size_t len, bson_type type ) {
 
-    int sl = len + 1;
+    size_t sl = len + 1;
     if ( bson_check_string( b, ( const char * )value, sl - 1 ) == BSON_ERROR )
         return BSON_ERROR;
     if ( bson_append_estart( b, type, name, 4 + sl ) == BSON_ERROR ) {
         return BSON_ERROR;
     }
-    bson_append32( b , &sl );
+    bson_append32_as_int( b , ( int )sl );
     bson_append( b , value , sl - 1 );
     bson_append( b , "\0" , 1 );
     return BSON_OK;
 }
 
@@ -766,56 +771,56 @@ MONGO_EXPORT int bson_append_symbol( bson *b, const char *name, const char *valu
 
 MONGO_EXPORT int bson_append_code( bson *b, const char *name, const char *value ) {
     return bson_append_string_base( b, name, value, strlen ( value ), BSON_CODE );
 }
 
-MONGO_EXPORT int bson_append_string_n( bson *b, const char *name, const char *value, int len ) {
+MONGO_EXPORT int bson_append_string_n( bson *b, const char *name, const char *value, size_t len ) {
     return bson_append_string_base( b, name, value, len, BSON_STRING );
 }
 
-MONGO_EXPORT int bson_append_symbol_n( bson *b, const char *name, const char *value, int len ) {
+MONGO_EXPORT int bson_append_symbol_n( bson *b, const char *name, const char *value, size_t len ) {
     return bson_append_string_base( b, name, value, len, BSON_SYMBOL );
 }
 
-MONGO_EXPORT int bson_append_code_n( bson *b, const char *name, const char *value, int len ) {
+MONGO_EXPORT int bson_append_code_n( bson *b, const char *name, const char *value, size_t len ) {
     return bson_append_string_base( b, name, value, len, BSON_CODE );
 }
 
 MONGO_EXPORT int bson_append_code_w_scope_n( bson *b, const char *name,
-        const char *code, int len, const bson *scope ) {
+        const char *code, size_t len, const bson *scope ) {
 
-    int sl, size;
+    size_t sl, size;
     if ( !scope ) return BSON_ERROR;
     sl = len + 1;
     size = 4 + 4 + sl + bson_size( scope );
     if ( bson_append_estart( b, BSON_CODEWSCOPE, name, size ) == BSON_ERROR )
         return BSON_ERROR;
-    bson_append32( b, &size );
+    bson_append32_as_int( b, ( int )size );
     bson_append32( b, &sl );
     bson_append( b, code, sl );
     bson_append( b, scope->data, bson_size( scope ) );
     return BSON_OK;
 }
 
 MONGO_EXPORT int bson_append_code_w_scope( bson *b, const char *name, const char *code, const bson *scope ) {
     return bson_append_code_w_scope_n( b, name, code, strlen ( code ), scope );
 }
 
-MONGO_EXPORT int bson_append_binary( bson *b, const char *name, char type, const char *str, int len ) {
+MONGO_EXPORT int bson_append_binary( bson *b, const char *name, char type, const char *str, size_t len ) {
     if ( type == BSON_BIN_BINARY_OLD ) {
         int subtwolen = len + 4;
         if ( bson_append_estart( b, BSON_BINDATA, name, 4+1+4+len ) == BSON_ERROR )
             return BSON_ERROR;
-        bson_append32( b, &subtwolen );
+        bson_append32_as_int( b, ( int )subtwolen );
         bson_append_byte( b, type );
-        bson_append32( b, &len );
+        bson_append32_as_int( b, ( int )len );
         bson_append( b, str, len );
     }
     else {
         if ( bson_append_estart( b, BSON_BINDATA, name, 4+1+len ) == BSON_ERROR )
             return BSON_ERROR;
-        bson_append32( b, &len );
+        bson_append32_as_int( b, ( int )len );
         bson_append_byte( b, type );
         bson_append( b, str, len );
     }
     return BSON_OK;
 }
@@ -832,12 +837,12 @@ MONGO_EXPORT int bson_append_new_oid( bson *b, const char *name ) {
     bson_oid_gen( &oid );
     return bson_append_oid( b, name, &oid );
 }
 
 MONGO_EXPORT int bson_append_regex( bson *b, const char *name, const char *pattern, const char *opts ) {
-    const int plen = strlen( pattern )+1;
-    const int olen = strlen( opts )+1;
+    const size_t plen = strlen( pattern )+1;
+    const size_t olen = strlen( opts )+1;
     if ( bson_append_estart( b, BSON_REGEX, name, plen + olen ) == BSON_ERROR )
         return BSON_ERROR;
     if ( bson_check_string( b, pattern, plen - 1 ) == BSON_ERROR )
         return BSON_ERROR;
     bson_append( b , pattern , plen );
@@ -853,22 +858,22 @@ MONGO_EXPORT int bson_append_bson( bson *b, const char *name, const bson *bson )
     return BSON_OK;
 }
 
 MONGO_EXPORT int bson_append_element( bson *b, const char *name_or_null, const bson_iterator *elem ) {
     bson_iterator next = *elem;
-    int size;
+    size_t size;
 
     bson_iterator_next( &next );
     size = next.cur - elem->cur;
 
     if ( name_or_null == NULL ) {
         if( bson_ensure_space( b, size ) == BSON_ERROR )
             return BSON_ERROR;
         bson_append( b, elem->cur, size );
     }
     else {
-        int data_size = size - 2 - strlen( bson_iterator_key( elem ) );
+        size_t data_size = size - 2 - strlen( bson_iterator_key( elem ) );
         bson_append_estart( b, elem->cur[0], name_or_null, data_size );
         bson_append( b, bson_iterator_value( elem ), data_size );
     }
 
     return BSON_OK;
@@ -920,11 +925,11 @@ MONGO_EXPORT int bson_append_finish_object( bson *b ) {
     int i;
     if ( bson_ensure_space( b, 1 ) == BSON_ERROR ) return BSON_ERROR;
     bson_append_byte( b , 0 );
 
     start = b->data + b->stack[ --b->stackPos ];
-    i = b->cur - start;
+    i = ( int )( b->cur - start );
     bson_little_endian32( start, &i );
 
     return BSON_OK;
 }
 
@@ -948,18 +953,18 @@ MONGO_EXPORT bson_err_handler set_bson_err_handler( bson_err_handler func ) {
 
 MONGO_EXPORT void bson_free( void *ptr ) {
     bson_free_func( ptr );
 }
 
-MONGO_EXPORT void *bson_malloc( int size ) {
+MONGO_EXPORT void *bson_malloc( size_t size ) {
     void *p;
     p = bson_malloc_func( size );
     bson_fatal_msg( !!p, "malloc() failed" );
     return p;
 }
 
-void *bson_realloc( void *ptr, int size ) {
+void *bson_realloc( void *ptr, size_t size ) {
     void *p;
     p = bson_realloc_func( ptr, size );
     bson_fatal_msg( !!p, "realloc() failed" );
     return p;
 }
diff --git a/src/bson.h b/src/bson.h
index 5982947..4808f0f 100644
--- a/src/bson.h
+++ b/src/bson.h
@@ -133,11 +133,11 @@ typedef struct {
 typedef struct {
     char *data;    /**< Pointer to a block of data in this BSON object. */
     char *cur;     /**< Pointer to the current position. */
     int dataSize;  /**< The number of bytes allocated to char *data. */
     bson_bool_t finished; /**< When finished, the BSON object can no longer be modified. */
-    int stack[32];        /**< A stack used to keep track of nested BSON elements. */
+    size_t stack[32];        /**< A stack used to keep track of nested BSON elements. */
     int stackPos;         /**< Index of current stack position. */
     int err; /**< Bitfield representing errors or warnings on this buffer */
     char *errstr; /**< A string representation of the most recent error or warning. */
 } bson;
 
@@ -168,11 +168,11 @@ MONGO_EXPORT void  bson_dispose(bson* b);
  * @param b the BSON object.
  *
  * @return the size.
  */
 MONGO_EXPORT int bson_size( const bson *b );
-MONGO_EXPORT int bson_buffer_size( const bson *b );
+MONGO_EXPORT size_t bson_buffer_size( const bson *b );
 
 /**
  * Print a string representation of a BSON object.
  *
  * @param b the BSON object to print.
@@ -600,11 +600,11 @@ void bson_init_size( bson *b, int size );
  * @param bytesNeeded the additional number of bytes needed.
  *
  * @return BSON_OK or BSON_ERROR with the bson error object set.
  *   Exits if allocation fails.
  */
-int bson_ensure_space( bson *b, const int bytesNeeded );
+int bson_ensure_space( bson *b, const size_t bytesNeeded );
 
 /**
  * Finalize a bson object.
  *
  * @param b the bson object to finalize.
@@ -715,11 +715,11 @@ MONGO_EXPORT int bson_append_string( bson *b, const char *name, const char *str
  * @param str the string to append.
  * @param len the number of bytes from str to append.
  *
  * @return BSON_OK or BSON_ERROR.
  */
-MONGO_EXPORT int bson_append_string_n( bson *b, const char *name, const char *str, int len );
+MONGO_EXPORT int bson_append_string_n( bson *b, const char *name, const char *str, size_t len );
 
 /**
  * Append a symbol to a bson.
  *
  * @param b the bson to append to.
@@ -738,11 +738,11 @@ MONGO_EXPORT int bson_append_symbol( bson *b, const char *name, const char *str
  * @param str the symbol to append.
  * @param len the number of bytes from str to append.
  *
  * @return BSON_OK or BSON_ERROR.
  */
-MONGO_EXPORT int bson_append_symbol_n( bson *b, const char *name, const char *str, int len );
+MONGO_EXPORT int bson_append_symbol_n( bson *b, const char *name, const char *str, size_t len );
 
 /**
  * Append code to a bson.
  *
  * @param b the bson to append to.
@@ -762,11 +762,11 @@ MONGO_EXPORT int bson_append_code( bson *b, const char *name, const char *str );
  * @param str the code to append.
  * @param len the number of bytes from str to append.
  *
  * @return BSON_OK or BSON_ERROR.
  */
-MONGO_EXPORT int bson_append_code_n( bson *b, const char *name, const char *str, int len );
+MONGO_EXPORT int bson_append_code_n( bson *b, const char *name, const char *str, size_t len );
 
 /**
  * Append code to a bson with scope.
  *
  * @param b the bson to append to.
@@ -787,11 +787,11 @@ MONGO_EXPORT int bson_append_code_w_scope( bson *b, const char *name, const char
  * @param len the number of bytes from str to append.
  * @param scope a BSON object containing the scope.
  *
  * @return BSON_OK or BSON_ERROR.
  */
-MONGO_EXPORT int bson_append_code_w_scope_n( bson *b, const char *name, const char *code, int size, const bson *scope );
+MONGO_EXPORT int bson_append_code_w_scope_n( bson *b, const char *name, const char *code, size_t size, const bson *scope );
 
 /**
  * Append binary data to a bson.
  *
  * @param b the bson to append to.
@@ -800,11 +800,11 @@ MONGO_EXPORT int bson_append_code_w_scope_n( bson *b, const char *name, const ch
  * @param str the binary data.
  * @param len the length of the data.
  *
  * @return BSON_OK or BSON_ERROR.
  */
-MONGO_EXPORT int bson_append_binary( bson *b, const char *name, char type, const char *str, int len );
+MONGO_EXPORT int bson_append_binary( bson *b, const char *name, char type, const char *str, size_t len );
 
 /**
  * Append a bson_bool_t to a bson.
  *
  * @param b the bson to append to.
@@ -975,11 +975,11 @@ MONGO_EXPORT void bson_free( void *ptr );
  *
  * @return a pointer to the allocated memory.
  *
  * @sa malloc(3)
  */
-MONGO_EXPORT void *bson_malloc( int size );
+MONGO_EXPORT void *bson_malloc( size_t size );
 
 /**
  * Changes the size of allocated memory and checks return value,
  * exiting fatally if realloc() fails.
  *
@@ -988,11 +988,11 @@ MONGO_EXPORT void *bson_malloc( int size );
  *
  * @return a pointer to the allocated memory.
  *
  * @sa realloc()
  */
-void *bson_realloc( void *ptr, int size );
+void *bson_realloc( void *ptr, size_t size );
 
 /**
  * Set a function for error handling.
  *
  * @param func a bson_err_handler function.
diff --git a/src/encoding.c b/src/encoding.c
index f325dcc..9a9017b 100644
--- a/src/encoding.c
+++ b/src/encoding.c
@@ -100,11 +100,11 @@ static int isLegalUTF8( const unsigned char *source, int length ) {
     }
     return 1;
 }
 
 /* If the name is part of a db ref ($ref, $db, or $id), then return true. */
-static int bson_string_is_db_ref( const unsigned char *string, const int length ) {
+static int bson_string_is_db_ref( const unsigned char *string, const size_t length ) {
     int result = 0;
 
     if( length >= 4 ) {
         if( string[1] == 'r' && string[2] == 'e' && string[3] == 'f' )
             result = 1;
@@ -118,14 +118,14 @@ static int bson_string_is_db_ref( const unsigned char *string, const int length
 
     return result;
 }
 
 static int bson_validate_string( bson *b, const unsigned char *string,
-                                 const int length, const char check_utf8, const char check_dot,
+                                 const size_t length, const char check_utf8, const char check_dot,
                                  const char check_dollar ) {
 
-    int position = 0;
+    size_t position = 0;
     int sequence_length = 1;
 
     if( check_dollar && string[0] == '$' ) {
         if( !bson_string_is_db_ref( string, length ) )
             b->err |= BSON_FIELD_INIT_DOLLAR;
@@ -153,15 +153,15 @@ static int bson_validate_string( bson *b, const unsigned char *string,
     return BSON_OK;
 }
 
 
 int bson_check_string( bson *b, const char *string,
-                       const int length ) {
+                       const size_t length ) {
 
     return bson_validate_string( b, ( const unsigned char * )string, length, 1, 0, 0 );
 }
 
 int bson_check_field_name( bson *b, const char *string,
-                           const int length ) {
+                           const size_t length ) {
 
     return bson_validate_string( b, ( const unsigned char * )string, length, 1, 1, 1 );
 }
diff --git a/src/encoding.h b/src/encoding.h
index f13c31e..ec34c2e 100644
--- a/src/encoding.h
+++ b/src/encoding.h
@@ -33,11 +33,11 @@ MONGO_EXTERN_C_START
  *     valid UTF8. This function will also check whether the string
  *     contains '.' or starts with '$', since the validity of this depends on context.
  *     Set the value of b->err appropriately.
  */
 int bson_check_field_name( bson *b, const char *string,
-                           const int length );
+                           const size_t length );
 
 /**
  * Check that a string is valid UTF8. Sets the buffer bit field appropriately.
  *
  * @param b The bson object to which string will be appended.
@@ -46,9 +46,9 @@ int bson_check_field_name( bson *b, const char *string,
  *
  * @return BSON_OK if valid UTF-8; otherwise, BSON_ERROR.
  *     Sets b->err on error.
  */
 bson_bool_t bson_check_string( bson *b, const char *string,
-                               const int length );
+                               const size_t length );
 
 MONGO_EXTERN_C_END
 #endif
diff --git a/src/env.c b/src/env.c
index 2aa8545..f428d44 100644
--- a/src/env.c
+++ b/src/env.c
@@ -36,16 +36,16 @@ typedef int socklen_t;
 
 int mongo_env_close_socket( int socket ) {
     return closesocket( socket );
 }
 
-int mongo_env_write_socket( mongo *conn, const void *buf, int len ) {
+int mongo_env_write_socket( mongo *conn, const void *buf, size_t len ) {
     const char *cbuf = buf;
     int flags = 0;
 
     while ( len ) {
-        int sent = send( conn->sock, cbuf, len, flags );
+        size_t sent = send( conn->sock, cbuf, len, flags );
         if ( sent == -1 ) {
             __mongo_set_error( conn, MONGO_IO_ERROR, NULL, WSAGetLastError() );
             conn->connected = 0;
             return MONGO_ERROR;
         }
@@ -54,15 +54,15 @@ int mongo_env_write_socket( mongo *conn, const void *buf, int len ) {
     }
 
     return MONGO_OK;
 }
 
-int mongo_env_read_socket( mongo *conn, void *buf, int len ) {
+int mongo_env_read_socket( mongo *conn, void *buf, size_t len ) {
     char *cbuf = buf;
 
     while ( len ) {
-        int sent = recv( conn->sock, cbuf, len, 0 );
+        size_t sent = recv( conn->sock, cbuf, len, 0 );
         if ( sent == 0 || sent == -1 ) {
             __mongo_set_error( conn, MONGO_IO_ERROR, NULL, WSAGetLastError() );
             return MONGO_ERROR;
         }
         cbuf += sent;
@@ -223,20 +223,20 @@ int mongo_env_close_socket( int socket ) {
 
 int mongo_env_sock_init( void ) {
     return 0;
 }
 
-int mongo_env_write_socket( mongo *conn, const void *buf, int len ) {
+int mongo_env_write_socket( mongo *conn, const void *buf, size_t len ) {
     const char *cbuf = buf;
 #ifdef __APPLE__
     int flags = 0;
 #else
     int flags = MSG_NOSIGNAL;
 #endif
 
     while ( len ) {
-        int sent = send( conn->sock, cbuf, len, flags );
+        size_t sent = send( conn->sock, cbuf, len, flags );
         if ( sent == -1 ) {
             if (errno == EPIPE)
                 conn->connected = 0;
             __mongo_set_error( conn, MONGO_IO_ERROR, strerror( errno ), errno );
             return MONGO_ERROR;
@@ -246,14 +246,14 @@ int mongo_env_write_socket( mongo *conn, const void *buf, int len ) {
     }
 
     return MONGO_OK;
 }
 
-int mongo_env_read_socket( mongo *conn, void *buf, int len ) {
+int mongo_env_read_socket( mongo *conn, void *buf, size_t len ) {
     char *cbuf = buf;
     while ( len ) {
-        int sent = recv( conn->sock, cbuf, len, 0 );
+        size_t sent = recv( conn->sock, cbuf, len, 0 );
         if ( sent == 0 || sent == -1 ) {
             __mongo_set_error( conn, MONGO_IO_ERROR, strerror( errno ), errno );
             return MONGO_ERROR;
         }
         cbuf += sent;
@@ -441,11 +441,11 @@ int mongo_env_close_socket( int socket ) {
 #else
     return close( socket );
 #endif
 }
 
-int mongo_env_write_socket( mongo *conn, const void *buf, int len ) {
+int mongo_env_write_socket( mongo *conn, const void *buf, size_t len ) {
     const char *cbuf = buf;
 #ifdef _WIN32
     int flags = 0;
 #else
 #ifdef __APPLE__
@@ -454,11 +454,11 @@ int mongo_env_write_socket( mongo *conn, const void *buf, int len ) {
     int flags = MSG_NOSIGNAL;
 #endif
 #endif
 
     while ( len ) {
-        int sent = send( conn->sock, cbuf, len, flags );
+        size_t sent = send( conn->sock, cbuf, len, flags );
         if ( sent == -1 ) {
             if (errno == EPIPE)
                 conn->connected = 0;
             conn->err = MONGO_IO_ERROR;
             return MONGO_ERROR;
@@ -468,14 +468,14 @@ int mongo_env_write_socket( mongo *conn, const void *buf, int len ) {
     }
 
     return MONGO_OK;
 }
 
-int mongo_env_read_socket( mongo *conn, void *buf, int len ) {
+int mongo_env_read_socket( mongo *conn, void *buf, size_t len ) {
     char *cbuf = buf;
     while ( len ) {
-        int sent = recv( conn->sock, cbuf, len, 0 );
+        size_t sent = recv( conn->sock, cbuf, len, 0 );
         if ( sent == 0 || sent == -1 ) {
             conn->err = MONGO_IO_ERROR;
             return MONGO_ERROR;
         }
         cbuf += sent;
diff --git a/src/env.h b/src/env.h
index 463ee32..f59845b 100644
--- a/src/env.h
+++ b/src/env.h
@@ -23,12 +23,12 @@
 
 MONGO_EXTERN_C_START
 
 /* This is a no-op in the generic implementation. */
 int mongo_env_set_socket_op_timeout( mongo *conn, int millis );
-int mongo_env_read_socket( mongo *conn, void *buf, int len );
-int mongo_env_write_socket( mongo *conn, const void *buf, int len );
+int mongo_env_read_socket( mongo *conn, void *buf, size_t len );
+int mongo_env_write_socket( mongo *conn, const void *buf, size_t len );
 int mongo_env_socket_connect( mongo *conn, const char *host, int port );
 
 /* Initialize socket services */
 MONGO_EXPORT int mongo_env_sock_init( void );
 
diff --git a/src/gridfs.c b/src/gridfs.c
index b0daf3b..cc11365 100644
--- a/src/gridfs.c
+++ b/src/gridfs.c
@@ -226,13 +226,13 @@ MONGO_EXPORT void gridfile_writer_init( gridfile *gfile, gridfs *gfs,
 }
 
 MONGO_EXPORT void gridfile_write_buffer( gridfile *gfile, const char *data,
         gridfs_offset length ) {
 
-    int bytes_left = 0;
-    int data_partial_len = 0;
-    int chunks_to_write = 0;
+    size_t bytes_left = 0;
+    size_t data_partial_len = 0;
+    size_t chunks_to_write = 0;
     char *buffer;
     bson *oChunk;
     gridfs_offset to_write = length + gfile->pending_len;
 
     if ( to_write < DEFAULT_CHUNK_SIZE ) { /* Less than one chunk to write */
@@ -588,11 +588,11 @@ MONGO_EXPORT void gridfile_get_chunk( gridfile *gfile, int n, bson* out ) {
         bson_empty(&empty);
         bson_copy(out, &empty);
     }
 }
 
-MONGO_EXPORT mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, int size ) {
+MONGO_EXPORT mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, size_t size ) {
     bson_iterator it;
     bson_oid_t id;
     bson gte;
     bson query;
     bson orderby;
@@ -603,15 +603,15 @@ MONGO_EXPORT mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, int
     id = *bson_iterator_oid( &it );
 
     bson_init( &query );
     bson_append_oid( &query, "files_id", &id );
     if ( size == 1 ) {
-        bson_append_int( &query, "n", start );
+        bson_append_int( &query, "n", (int)start );
     }
     else {
         bson_init( &gte );
-        bson_append_int( &gte, "$gte", start );
+        bson_append_int( &gte, "$gte", (int)start );
         bson_finish( &gte );
         bson_append_bson( &query, "n", &gte );
         bson_destroy( &gte );
     }
     bson_finish( &query );
@@ -624,11 +624,11 @@ MONGO_EXPORT mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, int
     bson_append_bson( &command, "query", &query );
     bson_append_bson( &command, "orderby", &orderby );
     bson_finish( &command );
 
     cursor = mongo_find( gfile->gfs->client, gfile->gfs->chunks_ns,
-                         &command, NULL, size, 0, 0 );
+                         &command, NULL, (int)size, 0, 0 );
 
     bson_destroy( &command );
     bson_destroy( &query );
     bson_destroy( &orderby );
 
@@ -657,13 +657,13 @@ gridfs_offset gridfile_write_file( gridfile *gfile, FILE *stream ) {
 
 MONGO_EXPORT gridfs_offset gridfile_read( gridfile *gfile, gridfs_offset size, char *buf ) {
     mongo_cursor *chunks;
     bson chunk;
 
-    int first_chunk;
-    int last_chunk;
-    int total_chunks;
+    size_t first_chunk;
+    size_t last_chunk;
+    size_t total_chunks;
     gridfs_offset chunksize;
     gridfs_offset contentlength;
     gridfs_offset bytes_left;
     int i;
     bson_iterator it;
diff --git a/src/gridfs.h b/src/gridfs.h
index fa6f7c9..5a25b6e 100644
--- a/src/gridfs.h
+++ b/src/gridfs.h
@@ -46,11 +46,11 @@ typedef struct {
     char *remote_name;  /**> The name of the gridfile as a string */
     char *content_type; /**> The gridfile's content type */
     gridfs_offset length; /**> The length of this gridfile */
     int chunk_num;      /**> The number of the current chunk being written to */
     char *pending_data; /**> A buffer storing data still to be written to chunks */
-    int pending_len;    /**> Length of pending_data buffer */
+    size_t pending_len;    /**> Length of pending_data buffer */
 } gridfile;
 
 MONGO_EXPORT gridfs* gridfs_create( void );
 MONGO_EXPORT void gridfs_dispose(gridfs* gfs);
 MONGO_EXPORT gridfile* gridfile_create( void );
@@ -291,11 +291,11 @@ MONGO_EXPORT void gridfile_get_chunk( gridfile *gfile, int n, bson* out );
  *  @param start - the first chunk in the cursor
  *  @param size - the number of chunks to be returned
  *
  *  @return - mongo_cursor of the chunks (must be destroyed after use)
  */
-MONGO_EXPORT mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, int size );
+MONGO_EXPORT mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, size_t size );
 
 /**
  *  Writes the GridFile to a stream
  *
  *  @param gfile - the working GridFile
diff --git a/src/mongo.c b/src/mongo.c
index eb4bf88..eb2b056 100644
--- a/src/mongo.c
+++ b/src/mongo.c
@@ -110,11 +110,11 @@ MONGO_EXPORT const char*  mongo_get_server_err_string(mongo* conn) {
     return conn->lasterrstr;
 }
 
 MONGO_EXPORT void __mongo_set_error( mongo *conn, mongo_error_t err, const char *str,
                                      int errcode ) {
-    int errstr_size, str_size;
+    size_t errstr_size, str_size;
 
     conn->err = err;
     conn->errcode = errcode;
 
     if( str ) {
@@ -263,18 +263,18 @@ static void mongo_set_last_error( mongo *conn, bson_iterator *it, bson *obj ) {
         conn->lasterrcode = bson_iterator_int( it );
 }
 
 static const int ZERO = 0;
 static const int ONE = 1;
-static mongo_message *mongo_message_create( int len , int id , int responseTo , int op ) {
+static mongo_message *mongo_message_create( size_t len , int id , int responseTo , int op ) {
     mongo_message *mm = ( mongo_message * )bson_malloc( len );
 
     if ( !id )
         id = rand();
 
     /* native endian (converted on send) */
-    mm->head.len = len;
+    mm->head.len = ( int )len;
     mm->head.id = id;
     mm->head.responseTo = responseTo;
     mm->head.op = op;
 
     return mm;
@@ -342,11 +342,11 @@ static int mongo_read_response( mongo *conn, mongo_reply **reply ) {
 
     return MONGO_OK;
 }
 
 
-static char *mongo_data_append( char *start , const void *data , int len ) {
+static char *mongo_data_append( char *start , const void *data , size_t len ) {
     memcpy( start , data , len );
     return start + len;
 }
 
 static char *mongo_data_append32( char *start , const void *data ) {
@@ -898,12 +898,12 @@ MONGO_EXPORT int mongo_insert_batch( mongo *conn, const char *ns,
 
     mongo_message *mm;
     mongo_write_concern *write_concern = NULL;
     int i;
     char *data;
-    int overhead =  16 + 4 + strlen( ns ) + 1;
-    int size = overhead;
+    size_t overhead =  16 + 4 + strlen( ns ) + 1;
+    size_t size = overhead;
 
     if( mongo_validate_ns( conn, ns ) != MONGO_OK )
         return MONGO_ERROR;
 
     for( i=0; i<count; i++ ) {
@@ -1202,11 +1202,11 @@ static int mongo_cursor_get_more( mongo_cursor *cursor ) {
         cursor->err = MONGO_CURSOR_EXHAUSTED;
         return MONGO_ERROR;
     }
     else {
         char *data;
-        int sl = strlen( cursor->ns )+1;
+        size_t sl = strlen( cursor->ns )+1;
         int limit = 0;
         mongo_message *mm;
 
         if( cursor->limit > 0 )
             limit = cursor->limit - cursor->seen;
@@ -1514,11 +1514,11 @@ MONGO_EXPORT double mongo_count( mongo *conn, const char *db, const char *ns, co
 MONGO_EXPORT int mongo_run_command( mongo *conn, const char *db, const bson *command,
                                     bson *out ) {
     int ret = MONGO_OK;
     bson response = {NULL, 0};
     bson fields;
-    int sl = strlen( db );
+    size_t sl = strlen( db );
     char *ns = bson_malloc( sl + 5 + 1 ); /* ".$cmd" + nul */
     int res, success = 0;
 
     strcpy( ns, db );
     strcpy( ns+sl, ".$cmd" );
@@ -1672,13 +1672,13 @@ static void digest2hex( mongo_md5_byte_t digest[16], char hex_digest[33] ) {
 static void mongo_pass_digest( const char *user, const char *pass, char hex_digest[33] ) {
     mongo_md5_state_t st;
     mongo_md5_byte_t digest[16];
 
     mongo_md5_init( &st );
-    mongo_md5_append( &st, ( const mongo_md5_byte_t * )user, strlen( user ) );
+    mongo_md5_append( &st, ( const mongo_md5_byte_t * )user, ( int )strlen( user ) );
     mongo_md5_append( &st, ( const mongo_md5_byte_t * )":mongo:", 7 );
-    mongo_md5_append( &st, ( const mongo_md5_byte_t * )pass, strlen( pass ) );
+    mongo_md5_append( &st, ( const mongo_md5_byte_t * )pass, ( int )strlen( pass ) );
     mongo_md5_finish( &st, digest );
     digest2hex( digest, hex_digest );
 }
 
 MONGO_EXPORT int mongo_cmd_add_user( mongo *conn, const char *db, const char *user, const char *pass ) {
@@ -1732,12 +1732,12 @@ MONGO_EXPORT bson_bool_t mongo_cmd_authenticate( mongo *conn, const char *db, co
     }
 
     mongo_pass_digest( user, pass, hex_digest );
 
     mongo_md5_init( &st );
-    mongo_md5_append( &st, ( const mongo_md5_byte_t * )nonce, strlen( nonce ) );
-    mongo_md5_append( &st, ( const mongo_md5_byte_t * )user, strlen( user ) );
+    mongo_md5_append( &st, ( const mongo_md5_byte_t * )nonce, ( int )strlen( nonce ) );
+    mongo_md5_append( &st, ( const mongo_md5_byte_t * )user, ( int )strlen( user ) );
     mongo_md5_append( &st, ( const mongo_md5_byte_t * )hex_digest, 32 );
     mongo_md5_finish( &st, digest );
     digest2hex( digest, hex_digest );
 
     bson_init( &cmd );

Vulnerable code:     unsigned int array_index_stack[ARRAY_INDEX_STACK_SIZE];
MONGO_EXPORT int bson_buffer_size( const bson *b ) {
    int ds;
        return bson_iterator_long_raw( i );
static void bson_append( bson *b, const void *data, int len ) {
int bson_ensure_space( bson *b, const int bytesNeeded ) {
        i = b->cur - b->data;
static int bson_append_estart( bson *b, int type, const char *name, const int dataSize ) {
                                    const char *value, int len, bson_type type ) {
    int sl = len + 1;
    bson_append32( b , &sl );
MONGO_EXPORT int bson_append_string_n( bson *b, const char *name, const char *value, int len ) {
MONGO_EXPORT int bson_append_symbol_n( bson *b, const char *name, const char *value, int len ) {
MONGO_EXPORT int bson_append_code_n( bson *b, const char *name, const char *value, int len ) {
        const char *code, int len, const bson *scope ) {
    int sl, size;
    bson_append32( b, &size );
MONGO_EXPORT int bson_append_binary( bson *b, const char *name, char type, const char *str, int len ) {
        bson_append32( b, &subtwolen );
        bson_append32( b, &len );
        bson_append32( b, &len );
    const int plen = strlen( pattern )+1;
    const int olen = strlen( opts )+1;
    int size;
        int data_size = size - 2 - strlen( bson_iterator_key( elem ) );
    i = b->cur - start;
MONGO_EXPORT void *bson_malloc( int size ) {
void *bson_realloc( void *ptr, int size ) {
    int stack[32];        /**< A stack used to keep track of nested BSON elements. */
MONGO_EXPORT int bson_buffer_size( const bson *b );
int bson_ensure_space( bson *b, const int bytesNeeded );
MONGO_EXPORT int bson_append_string_n( bson *b, const char *name, const char *str, int len );
MONGO_EXPORT int bson_append_symbol_n( bson *b, const char *name, const char *str, int len );
MONGO_EXPORT int bson_append_code_n( bson *b, const char *name, const char *str, int len );
MONGO_EXPORT int bson_append_code_w_scope_n( bson *b, const char *name, const char *code, int size, const bson *scope );
MONGO_EXPORT int bson_append_binary( bson *b, const char *name, char type, const char *str, int len );
MONGO_EXPORT void *bson_malloc( int size );
void *bson_realloc( void *ptr, int size );
static int bson_string_is_db_ref( const unsigned char *string, const int length ) {
                                 const int length, const char check_utf8, const char check_dot,
    int position = 0;
                       const int length ) {
                           const int length ) {
                           const int length );
                               const int length );
int mongo_env_write_socket( mongo *conn, const void *buf, int len ) {
        int sent = send( conn->sock, cbuf, len, flags );
int mongo_env_read_socket( mongo *conn, void *buf, int len ) {
        int sent = recv( conn->sock, cbuf, len, 0 );
int mongo_env_write_socket( mongo *conn, const void *buf, int len ) {
        int sent = send( conn->sock, cbuf, len, flags );
int mongo_env_read_socket( mongo *conn, void *buf, int len ) {
        int sent = recv( conn->sock, cbuf, len, 0 );
int mongo_env_write_socket( mongo *conn, const void *buf, int len ) {
        int sent = send( conn->sock, cbuf, len, flags );
int mongo_env_read_socket( mongo *conn, void *buf, int len ) {
        int sent = recv( conn->sock, cbuf, len, 0 );
int mongo_env_read_socket( mongo *conn, void *buf, int len );
int mongo_env_write_socket( mongo *conn, const void *buf, int len );
    int bytes_left = 0;
    int data_partial_len = 0;
    int chunks_to_write = 0;
MONGO_EXPORT mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, int size ) {
        bson_append_int( &query, "n", start );
        bson_append_int( &gte, "$gte", start );
                         &command, NULL, size, 0, 0 );
    int first_chunk;
    int last_chunk;
    int total_chunks;
    int pending_len;    /**> Length of pending_data buffer */
MONGO_EXPORT mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, int size );
    int errstr_size, str_size;
static mongo_message *mongo_message_create( int len , int id , int responseTo , int op ) {
    mm->head.len = len;
static char *mongo_data_append( char *start , const void *data , int len ) {
    int overhead =  16 + 4 + strlen( ns ) + 1;
    int size = overhead;
        int sl = strlen( cursor->ns )+1;
    int sl = strlen( db );
    mongo_md5_append( &st, ( const mongo_md5_byte_t * )user, strlen( user ) );
    mongo_md5_append( &st, ( const mongo_md5_byte_t * )pass, strlen( pass ) );
    mongo_md5_append( &st, ( const mongo_md5_byte_t * )nonce, strlen( nonce ) );
    mongo_md5_append( &st, ( const mongo_md5_byte_t * )user, strlen( user ) );
Fixed code:     size_t array_index_stack[ARRAY_INDEX_STACK_SIZE];
MONGO_EXPORT size_t bson_buffer_size( const bson *b ) {
    size_t ds;
        return ( int )bson_iterator_long_raw( i );
static void bson_append( bson *b, const void *data, size_t len ) {
static void bson_append32_as_int( bson *b, int data ) {
    bson_little_endian32( b->cur, &data );
    b->cur += 4;
}

int bson_ensure_space( bson *b, const size_t bytesNeeded ) {
        i = ( int )( b->cur - b->data );
static int bson_append_estart( bson *b, int type, const char *name, const size_t dataSize ) {
                                    const char *value, size_t len, bson_type type ) {
    size_t sl = len + 1;
    bson_append32_as_int( b , ( int )sl );
MONGO_EXPORT int bson_append_string_n( bson *b, const char *name, const char *value, size_t len ) {
MONGO_EXPORT int bson_append_symbol_n( bson *b, const char *name, const char *value, size_t len ) {
MONGO_EXPORT int bson_append_code_n( bson *b, const char *name, const char *value, size_t len ) {
        const char *code, size_t len, const bson *scope ) {
    size_t sl, size;
    bson_append32_as_int( b, ( int )size );
MONGO_EXPORT int bson_append_binary( bson *b, const char *name, char type, const char *str, size_t len ) {
        bson_append32_as_int( b, ( int )subtwolen );
        bson_append32_as_int( b, ( int )len );
        bson_append32_as_int( b, ( int )len );
    const size_t plen = strlen( pattern )+1;
    const size_t olen = strlen( opts )+1;
    size_t size;
        size_t data_size = size - 2 - strlen( bson_iterator_key( elem ) );
    i = ( int )( b->cur - start );
MONGO_EXPORT void *bson_malloc( size_t size ) {
void *bson_realloc( void *ptr, size_t size ) {
    size_t stack[32];        /**< A stack used to keep track of nested BSON elements. */
MONGO_EXPORT size_t bson_buffer_size( const bson *b );
int bson_ensure_space( bson *b, const size_t bytesNeeded );
MONGO_EXPORT int bson_append_string_n( bson *b, const char *name, const char *str, size_t len );
MONGO_EXPORT int bson_append_symbol_n( bson *b, const char *name, const char *str, size_t len );
MONGO_EXPORT int bson_append_code_n( bson *b, const char *name, const char *str, size_t len );
MONGO_EXPORT int bson_append_code_w_scope_n( bson *b, const char *name, const char *code, size_t size, const bson *scope );
MONGO_EXPORT int bson_append_binary( bson *b, const char *name, char type, const char *str, size_t len );
MONGO_EXPORT void *bson_malloc( size_t size );
void *bson_realloc( void *ptr, size_t size );
static int bson_string_is_db_ref( const unsigned char *string, const size_t length ) {
                                 const size_t length, const char check_utf8, const char check_dot,
    size_t position = 0;
                       const size_t length ) {
                           const size_t length ) {
                           const size_t length );
                               const size_t length );
int mongo_env_write_socket( mongo *conn, const void *buf, size_t len ) {
        size_t sent = send( conn->sock, cbuf, len, flags );
int mongo_env_read_socket( mongo *conn, void *buf, size_t len ) {
        size_t sent = recv( conn->sock, cbuf, len, 0 );
int mongo_env_write_socket( mongo *conn, const void *buf, size_t len ) {
        size_t sent = send( conn->sock, cbuf, len, flags );
int mongo_env_read_socket( mongo *conn, void *buf, size_t len ) {
        size_t sent = recv( conn->sock, cbuf, len, 0 );
int mongo_env_write_socket( mongo *conn, const void *buf, size_t len ) {
        size_t sent = send( conn->sock, cbuf, len, flags );
int mongo_env_read_socket( mongo *conn, void *buf, size_t len ) {
        size_t sent = recv( conn->sock, cbuf, len, 0 );
int mongo_env_read_socket( mongo *conn, void *buf, size_t len );
int mongo_env_write_socket( mongo *conn, const void *buf, size_t len );
    size_t bytes_left = 0;
    size_t data_partial_len = 0;
    size_t chunks_to_write = 0;
MONGO_EXPORT mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, size_t size ) {
        bson_append_int( &query, "n", (int)start );
        bson_append_int( &gte, "$gte", (int)start );
                         &command, NULL, (int)size, 0, 0 );
    size_t first_chunk;
    size_t last_chunk;
    size_t total_chunks;
    size_t pending_len;    /**> Length of pending_data buffer */
MONGO_EXPORT mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, size_t size );
    size_t errstr_size, str_size;
static mongo_message *mongo_message_create( size_t len , int id , int responseTo , int op ) {
    mm->head.len = ( int )len;
static char *mongo_data_append( char *start , const void *data , size_t len ) {
    size_t overhead =  16 + 4 + strlen( ns ) + 1;
    size_t size = overhead;
        size_t sl = strlen( cursor->ns )+1;
    size_t sl = strlen( db );
    mongo_md5_append( &st, ( const mongo_md5_byte_t * )user, ( int )strlen( user ) );
    mongo_md5_append( &st, ( const mongo_md5_byte_t * )pass, ( int )strlen( pass ) );
    mongo_md5_append( &st, ( const mongo_md5_byte_t * )nonce, ( int )strlen( nonce ) );
    mongo_md5_append( &st, ( const mongo_md5_byte_t * )user, ( int )strlen( user ) );