GUACAMOLE-1867: Merge new libguac memory convenience functions.

This commit is contained in:
James Muehlner 2023-10-25 20:33:38 -07:00 committed by GitHub
commit 690808dabd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
129 changed files with 2813 additions and 570 deletions

View File

@ -50,7 +50,8 @@ SHOW_INCLUDE_FILES = NO
#
CASE_SENSE_NAMES = YES
EXCLUDE_SYMBOLS = __* guac_palette*
EXCLUDE_SYMBOLS = __* guac_palette* PRIV_*
EXCLUDE_PATTERNS = **/private/*.h
FILE_PATTERNS = *.h
INPUT = ../../src/libguac/guacamole
JAVADOC_AUTOBRIEF = YES

View File

@ -22,6 +22,8 @@
#include <openssl/bn.h>
#include <openssl/ossl_typ.h>
#include <guacamole/mem.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
@ -67,7 +69,7 @@ void guac_common_ssh_buffer_write_bignum(char** buffer, const BIGNUM* value) {
/* Allocate output buffer, add padding byte */
length = BN_num_bytes(value);
bn_buffer = malloc(length);
bn_buffer = guac_mem_alloc(length);
/* Convert BIGNUM */
BN_bn2bin(value, bn_buffer);
@ -84,7 +86,7 @@ void guac_common_ssh_buffer_write_bignum(char** buffer, const BIGNUM* value) {
memcpy(*buffer, bn_buffer, length);
*buffer += length;
free(bn_buffer);
guac_mem_free(bn_buffer);
}

View File

@ -38,7 +38,7 @@
*
* @return
* A newly-allocated string containing the credentials provided by
* the user, which must be freed by a call to free().
* the user, which must be freed by a call to guac_mem_free().
*/
typedef char* guac_ssh_credential_handler(guac_client* client, char* cred_name);

View File

@ -22,6 +22,7 @@
#include "common-ssh/buffer.h"
#include "common-ssh/key.h"
#include <guacamole/mem.h>
#include <guacamole/string.h>
#include <openssl/bio.h>
@ -137,13 +138,13 @@ guac_common_ssh_key* guac_common_ssh_key_alloc(char* data, int length,
if (is_passphrase_needed(data, length) && (passphrase == NULL || *passphrase == '\0'))
return NULL;
guac_common_ssh_key* key = malloc(sizeof(guac_common_ssh_key));
guac_common_ssh_key* key = guac_mem_alloc(sizeof(guac_common_ssh_key));
/* Copy private key to structure */
key->private_key_length = length;
key->private_key = malloc(length);
key->private_key = guac_mem_alloc(length);
memcpy(key->private_key, data, length);
key->passphrase = strdup(passphrase);
key->passphrase = guac_strdup(passphrase);
return key;
@ -157,10 +158,9 @@ const char* guac_common_ssh_key_error() {
}
void guac_common_ssh_key_free(guac_common_ssh_key* key) {
free(key->private_key);
free(key->passphrase);
free(key);
guac_mem_free(key->private_key);
guac_mem_free(key->passphrase);
guac_mem_free(key);
}
int guac_common_ssh_verify_host_key(LIBSSH2_SESSION* session, guac_client* client,

View File

@ -21,6 +21,7 @@
#include "common-ssh/ssh.h"
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <guacamole/object.h>
#include <guacamole/protocol.h>
#include <guacamole/socket.h>
@ -622,7 +623,7 @@ static int guac_common_ssh_sftp_ls_ack_handler(guac_user* user,
if (status != GUAC_PROTOCOL_STATUS_SUCCESS) {
libssh2_sftp_closedir(list_state->directory);
guac_user_free_stream(user, stream);
free(list_state);
guac_mem_free(list_state);
return 0;
}
@ -674,7 +675,7 @@ static int guac_common_ssh_sftp_ls_ack_handler(guac_user* user,
/* Clean up resources */
libssh2_sftp_closedir(list_state->directory);
free(list_state);
guac_mem_free(list_state);
/* Signal of stream */
guac_protocol_send_end(user->socket, stream);
@ -774,7 +775,7 @@ static int guac_common_ssh_sftp_get_handler(guac_user* user,
/* Init directory listing state */
guac_common_ssh_sftp_ls_state* list_state =
malloc(sizeof(guac_common_ssh_sftp_ls_state));
guac_mem_alloc(sizeof(guac_common_ssh_sftp_ls_state));
list_state->directory = dir;
list_state->filesystem = filesystem;
@ -786,7 +787,7 @@ static int guac_common_ssh_sftp_get_handler(guac_user* user,
if (length >= sizeof(list_state->directory_name)) {
guac_user_log(user, GUAC_LOG_INFO, "Unable to read directory "
"\"%s\": Path too long", fullpath);
free(list_state);
guac_mem_free(list_state);
return 0;
}
@ -969,7 +970,7 @@ guac_common_ssh_sftp_filesystem* guac_common_ssh_create_sftp_filesystem(
/* Allocate data for SFTP session */
guac_common_ssh_sftp_filesystem* filesystem =
malloc(sizeof(guac_common_ssh_sftp_filesystem));
guac_mem_alloc(sizeof(guac_common_ssh_sftp_filesystem));
/* Associate SSH session with SFTP data and user */
filesystem->ssh_session = session;
@ -984,15 +985,15 @@ guac_common_ssh_sftp_filesystem* guac_common_ssh_create_sftp_filesystem(
root_path)) {
guac_client_log(session->client, GUAC_LOG_WARNING, "Cannot create "
"SFTP filesystem - \"%s\" is not a valid path.", root_path);
free(filesystem);
guac_mem_free(filesystem);
return NULL;
}
/* Generate filesystem name from root path if no name is provided */
if (name != NULL)
filesystem->name = strdup(name);
filesystem->name = guac_strdup(name);
else
filesystem->name = strdup(filesystem->root_path);
filesystem->name = guac_strdup(filesystem->root_path);
/* Initially upload files to current directory */
strcpy(filesystem->upload_path, ".");
@ -1009,8 +1010,8 @@ void guac_common_ssh_destroy_sftp_filesystem(
libssh2_sftp_shutdown(filesystem->sftp_session);
/* Free associated memory */
free(filesystem->name);
free(filesystem);
guac_mem_free(filesystem->name);
guac_mem_free(filesystem);
}

View File

@ -23,6 +23,8 @@
#include <guacamole/client.h>
#include <guacamole/fips.h>
#include <guacamole/mem.h>
#include <guacamole/string.h>
#include <libssh2.h>
#ifdef LIBSSH2_USES_GCRYPT
@ -120,7 +122,7 @@ static void guac_common_ssh_openssl_init_locks(int count) {
/* Allocate required number of locks */
guac_common_ssh_openssl_locks =
malloc(sizeof(pthread_mutex_t) * count);
guac_mem_alloc(sizeof(pthread_mutex_t), count);
/* Initialize each lock */
for (i=0; i < count; i++)
@ -147,7 +149,7 @@ static void guac_common_ssh_openssl_free_locks(int count) {
pthread_mutex_destroy(&(guac_common_ssh_openssl_locks[i]));
/* Free lock array */
free(guac_common_ssh_openssl_locks);
guac_mem_free(guac_common_ssh_openssl_locks);
}
#endif
@ -249,7 +251,7 @@ static void guac_common_ssh_kbd_callback(const char *name, int name_len,
/* Send password if only one prompt */
if (num_prompts == 1) {
char* password = common_session->user->password;
responses[0].text = strdup(password);
responses[0].text = guac_strdup(password);
responses[0].length = strlen(password);
}
@ -486,7 +488,7 @@ guac_common_ssh_session* guac_common_ssh_create_session(guac_client* client,
/* Allocate new session */
guac_common_ssh_session* common_session =
malloc(sizeof(guac_common_ssh_session));
guac_mem_alloc(sizeof(guac_common_ssh_session));
/* Open SSH session */
LIBSSH2_SESSION* session = libssh2_session_init_ex(NULL, NULL,
@ -494,7 +496,7 @@ guac_common_ssh_session* guac_common_ssh_create_session(guac_client* client,
if (session == NULL) {
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
"Session allocation failed.");
free(common_session);
guac_mem_free(common_session);
close(fd);
return NULL;
}
@ -514,7 +516,7 @@ guac_common_ssh_session* guac_common_ssh_create_session(guac_client* client,
if (libssh2_session_handshake(session, fd)) {
guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR,
"SSH handshake failed.");
free(common_session);
guac_mem_free(common_session);
close(fd);
return NULL;
}
@ -527,7 +529,7 @@ guac_common_ssh_session* guac_common_ssh_create_session(guac_client* client,
if (!remote_hostkey) {
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
"Failed to get host key for %s", hostname);
free(common_session);
guac_mem_free(common_session);
close(fd);
return NULL;
}
@ -550,7 +552,7 @@ guac_common_ssh_session* guac_common_ssh_create_session(guac_client* client,
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
"Host key did not match any provided known host keys. %s", err_msg);
free(common_session);
guac_mem_free(common_session);
close(fd);
return NULL;
}
@ -564,7 +566,7 @@ guac_common_ssh_session* guac_common_ssh_create_session(guac_client* client,
/* Attempt authentication */
if (guac_common_ssh_authenticate(common_session)) {
free(common_session);
guac_mem_free(common_session);
close(fd);
return NULL;
}
@ -595,6 +597,6 @@ void guac_common_ssh_destroy_session(guac_common_ssh_session* session) {
libssh2_session_free(session->session);
/* Free all other data */
free(session);
guac_mem_free(session);
}

View File

@ -19,6 +19,8 @@
#include "common-ssh/sftp.h"
#include <guacamole/mem.h>
#include <CUnit/CUnit.h>
#include <stdlib.h>
@ -160,7 +162,7 @@ void test_sftp__normalize_relative_mixed() {
* Generates a dynamically-allocated path having the given number of bytes, not
* counting the null-terminator. The path will contain only UNIX-style path
* separators. The returned path must eventually be freed with a call to
* free().
* guac_mem_free().
*
* @param length
* The number of bytes to include in the generated path, not counting the
@ -174,16 +176,16 @@ void test_sftp__normalize_relative_mixed() {
* @return
* A dynamically-allocated path containing the given number of bytes, not
* counting the null-terminator. This path must eventually be freed with a
* call to free().
* call to guac_mem_free().
*/
static char* generate_path(int length, int max_depth) {
/* If no length given, calculate space required from max_depth */
if (length == -1)
length = max_depth * 2;
length = guac_mem_ckd_mul_or_die(max_depth, 2);
int i;
char* input = malloc(length + 1);
char* input = guac_mem_alloc(guac_mem_ckd_add_or_die(length, 1));
/* Fill path with /x/x/x/x/x/x/x/x/x/x/.../xxxxxxxxx... */
for (i = 0; i < length; i++) {
@ -214,17 +216,17 @@ void test_sftp__normalize_long() {
/* Exceeds maximum length by a factor of 2 */
input = generate_path(GUAC_COMMON_SSH_SFTP_MAX_PATH * 2, GUAC_COMMON_SSH_SFTP_MAX_DEPTH);
CU_ASSERT_EQUAL(guac_common_ssh_sftp_normalize_path(normalized, input), 0);
free(input);
guac_mem_free(input);
/* Exceeds maximum length by one byte */
input = generate_path(GUAC_COMMON_SSH_SFTP_MAX_PATH, GUAC_COMMON_SSH_SFTP_MAX_DEPTH);
CU_ASSERT_EQUAL(guac_common_ssh_sftp_normalize_path(normalized, input), 0);
free(input);
guac_mem_free(input);
/* Exactly maximum length */
input = generate_path(GUAC_COMMON_SSH_SFTP_MAX_PATH - 1, GUAC_COMMON_SSH_SFTP_MAX_DEPTH);
CU_ASSERT_NOT_EQUAL(guac_common_ssh_sftp_normalize_path(normalized, input), 0);
free(input);
guac_mem_free(input);
}
@ -240,24 +242,24 @@ void test_sftp__normalize_deep() {
/* Exceeds maximum depth by a factor of 2 */
input = generate_path(-1, GUAC_COMMON_SSH_SFTP_MAX_DEPTH * 2);
CU_ASSERT_EQUAL(guac_common_ssh_sftp_normalize_path(normalized, input), 0);
free(input);
guac_mem_free(input);
/* Exceeds maximum depth by one component */
input = generate_path(-1, GUAC_COMMON_SSH_SFTP_MAX_DEPTH + 1);
CU_ASSERT_EQUAL(guac_common_ssh_sftp_normalize_path(normalized, input), 0);
free(input);
guac_mem_free(input);
/* Exactly maximum depth (should still be rejected as SFTP depth limits are
* set such that a path with the maximum depth will exceed the maximum
* length) */
input = generate_path(-1, GUAC_COMMON_SSH_SFTP_MAX_DEPTH);
CU_ASSERT_EQUAL(guac_common_ssh_sftp_normalize_path(normalized, input), 0);
free(input);
guac_mem_free(input);
/* Less than maximum depth */
input = generate_path(-1, GUAC_COMMON_SSH_SFTP_MAX_DEPTH - 1);
CU_ASSERT_NOT_EQUAL(guac_common_ssh_sftp_normalize_path(normalized, input), 0);
free(input);
guac_mem_free(input);
}

View File

@ -20,15 +20,18 @@
#include "common-ssh/key.h"
#include "common-ssh/user.h"
#include <guacamole/mem.h>
#include <guacamole/string.h>
#include <stdlib.h>
#include <string.h>
guac_common_ssh_user* guac_common_ssh_create_user(const char* username) {
guac_common_ssh_user* user = malloc(sizeof(guac_common_ssh_user));
guac_common_ssh_user* user = guac_mem_alloc(sizeof(guac_common_ssh_user));
/* Init user */
user->username = strdup(username);
user->username = guac_strdup(username);
user->password = NULL;
user->private_key = NULL;
@ -43,9 +46,9 @@ void guac_common_ssh_destroy_user(guac_common_ssh_user* user) {
guac_common_ssh_key_free(user->private_key);
/* Free all other data */
free(user->password);
free(user->username);
free(user);
guac_mem_free(user->password);
guac_mem_free(user->username);
guac_mem_free(user);
}
@ -53,8 +56,8 @@ void guac_common_ssh_user_set_password(guac_common_ssh_user* user,
const char* password) {
/* Replace current password with given value */
free(user->password);
user->password = strdup(password);
guac_mem_free(user->password);
user->password = guac_strdup(password);
}

View File

@ -21,6 +21,7 @@
#include "common/clipboard.h"
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <guacamole/protocol.h>
#include <guacamole/stream.h>
#include <guacamole/string.h>
@ -31,11 +32,11 @@
guac_common_clipboard* guac_common_clipboard_alloc() {
guac_common_clipboard* clipboard = malloc(sizeof(guac_common_clipboard));
guac_common_clipboard* clipboard = guac_mem_alloc(sizeof(guac_common_clipboard));
/* Init clipboard */
clipboard->mimetype[0] = '\0';
clipboard->buffer = malloc(GUAC_COMMON_CLIPBOARD_MAX_LENGTH);
clipboard->buffer = guac_mem_alloc(GUAC_COMMON_CLIPBOARD_MAX_LENGTH);
clipboard->available = GUAC_COMMON_CLIPBOARD_MAX_LENGTH;
clipboard->length = 0;
@ -51,10 +52,11 @@ void guac_common_clipboard_free(guac_common_clipboard* clipboard) {
pthread_mutex_destroy(&(clipboard->lock));
/* Free buffer */
free(clipboard->buffer);
guac_mem_free(clipboard->buffer);
/* Free base structure */
free(clipboard);
guac_mem_free(clipboard);
}
/**

View File

@ -68,7 +68,7 @@ typedef struct guac_common_cursor {
/**
* The size of the image data buffer, in bytes.
*/
int image_buffer_size;
size_t image_buffer_size;
/**
* The current cursor image, if any. If the mouse cursor has not yet been

View File

@ -22,24 +22,36 @@
#include "config.h"
#include <stddef.h>
/**
* Counts the number of occurrences of a given character in a string.
*
* @param string The string to count occurrences within.
* @param c The character to count occurrences of.
* @return The number of occurrences.
* @param string
* The string to count occurrences within.
*
* @param c
* The character to count occurrences of.
*
* @return
* The number of occurrences.
*/
int guac_count_occurrences(const char* string, char c);
size_t guac_count_occurrences(const char* string, char c);
/**
* Splits a string into a newly-allocated array of strings. The array itself
* and each string within the array will eventually need to be freed. The array
* is NULL-terminated.
* and each string within the array will eventually need to be freed through
* calls to guac_mem_free(). The array is NULL-terminated.
*
* @param string The string to split.
* @param delim The character which separates individual substrings within the
* given string.
* @return A newly-allocated, NULL-terminated array of strings.
* @param string
* The string to split.
*
* @param delim
* The character which separates individual substrings within the
* given string.
*
* @return
* A newly-allocated, NULL-terminated array of strings.
*/
char** guac_split(const char* string, char delim);

View File

@ -26,6 +26,7 @@
#include <cairo/cairo.h>
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <guacamole/protocol.h>
#include <guacamole/socket.h>
#include <guacamole/timestamp.h>
@ -48,7 +49,7 @@
*/
guac_common_cursor* guac_common_cursor_alloc(guac_client* client) {
guac_common_cursor* cursor = malloc(sizeof(guac_common_cursor));
guac_common_cursor* cursor = guac_mem_alloc(sizeof(guac_common_cursor));
if (cursor == NULL)
return NULL;
@ -58,7 +59,7 @@ guac_common_cursor* guac_common_cursor_alloc(guac_client* client) {
/* Allocate initial image buffer */
cursor->image_buffer_size = GUAC_COMMON_CURSOR_DEFAULT_SIZE;
cursor->image_buffer = malloc(cursor->image_buffer_size);
cursor->image_buffer = guac_mem_alloc(cursor->image_buffer_size);
/* No cursor image yet */
cursor->width = 0;
@ -90,7 +91,7 @@ void guac_common_cursor_free(guac_common_cursor* cursor) {
cairo_surface_t* surface = cursor->surface;
/* Free image buffer and surface */
free(cursor->image_buffer);
guac_mem_free(cursor->image_buffer);
if (surface != NULL)
cairo_surface_destroy(surface);
@ -100,7 +101,7 @@ void guac_common_cursor_free(guac_common_cursor* cursor) {
/* Return buffer to pool */
guac_client_free_buffer(client, buffer);
free(cursor);
guac_mem_free(cursor);
}
@ -206,17 +207,17 @@ void guac_common_cursor_update(guac_common_cursor* cursor, guac_user* user,
static void guac_common_cursor_resize(guac_common_cursor* cursor,
int width, int height, int stride) {
int minimum_size = height * stride;
size_t minimum_size = guac_mem_ckd_mul_or_die(height, stride);
/* Grow image buffer if necessary */
if (cursor->image_buffer_size < minimum_size) {
/* Calculate new size */
cursor->image_buffer_size = minimum_size*2;
cursor->image_buffer_size = guac_mem_ckd_mul_or_die(minimum_size, 2);
/* Destructively reallocate image buffer */
free(cursor->image_buffer);
cursor->image_buffer = malloc(cursor->image_buffer_size);
guac_mem_free(cursor->image_buffer);
cursor->image_buffer = guac_mem_alloc(cursor->image_buffer_size);
}

View File

@ -22,6 +22,7 @@
#include "common/surface.h"
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <guacamole/socket.h>
#include <pthread.h>
@ -92,7 +93,7 @@ static void guac_common_display_free_layers(guac_common_display_layer* layers,
guac_client_free_layer(client, layer);
/* Free current element and advance to next */
free(current);
guac_mem_free(current);
current = next;
}
@ -119,14 +120,14 @@ guac_common_display* guac_common_display_alloc(guac_client* client,
int width, int height) {
/* Allocate display */
guac_common_display* display = malloc(sizeof(guac_common_display));
guac_common_display* display = guac_mem_alloc(sizeof(guac_common_display));
if (display == NULL)
return NULL;
/* Allocate shared cursor */
display->cursor = guac_common_cursor_alloc(client);
if (display->cursor == NULL) {
free(display);
guac_mem_free(display);
return NULL;
}
@ -159,7 +160,7 @@ void guac_common_display_free(guac_common_display* display) {
guac_common_display_free_layers(display->layers, display->client);
pthread_mutex_destroy(&display->_lock);
free(display);
guac_mem_free(display);
}
@ -252,7 +253,7 @@ static guac_common_display_layer* guac_common_display_add_layer(
guac_common_display_layer* old_head = *head;
guac_common_display_layer* display_layer =
malloc(sizeof(guac_common_display_layer));
guac_mem_alloc(sizeof(guac_common_display_layer));
/* Init layer/surface pair */
display_layer->layer = layer;
@ -361,7 +362,7 @@ void guac_common_display_free_layer(guac_common_display* display,
guac_client_free_layer(display->client, display_layer->layer);
/* Free list element */
free(display_layer);
guac_mem_free(display_layer);
pthread_mutex_unlock(&display->_lock);
@ -380,7 +381,7 @@ void guac_common_display_free_buffer(guac_common_display* display,
guac_client_free_buffer(display->client, display_buffer->layer);
/* Free list element */
free(display_buffer);
guac_mem_free(display_buffer);
pthread_mutex_unlock(&display->_lock);

View File

@ -20,12 +20,14 @@
#include "config.h"
#include "common/list.h"
#include <guacamole/mem.h>
#include <stdlib.h>
#include <pthread.h>
guac_common_list* guac_common_list_alloc() {
guac_common_list* list = malloc(sizeof(guac_common_list));
guac_common_list* list = guac_mem_alloc(sizeof(guac_common_list));
pthread_mutex_init(&list->_lock, NULL);
list->head = NULL;
@ -47,12 +49,12 @@ void guac_common_list_free(
if (free_element_handler != NULL)
free_element_handler(element->data);
free(element);
guac_mem_free(element);
element = next;
}
/* Free the list itself */
free(list);
guac_mem_free(list);
}
@ -61,7 +63,7 @@ guac_common_list_element* guac_common_list_add(guac_common_list* list,
/* Allocate element, initialize as new head */
guac_common_list_element* element =
malloc(sizeof(guac_common_list_element));
guac_mem_alloc(sizeof(guac_common_list_element));
element->data = data;
element->next = list->head;
element->_ptr = &(list->head);
@ -85,7 +87,7 @@ void guac_common_list_remove(guac_common_list* list,
if (element->next != NULL)
element->next->_ptr = element->_ptr;
free(element);
guac_mem_free(element);
}

View File

@ -21,18 +21,20 @@
#include "common/string.h"
#include <guacamole/mem.h>
#include <stdlib.h>
#include <string.h>
int guac_count_occurrences(const char* string, char c) {
size_t guac_count_occurrences(const char* string, char c) {
int count = 0;
size_t count = 0;
while (*string != 0) {
/* Count each occurrence */
if (*string == c)
count++;
count = guac_mem_ckd_add_or_die(count, 1);
/* Next character */
string++;
@ -45,17 +47,18 @@ int guac_count_occurrences(const char* string, char c) {
char** guac_split(const char* string, char delim) {
int i = 0;
size_t i = 0;
int token_count = guac_count_occurrences(string, delim) + 1;
/* Calculate number of tokens present based on number of delimiters */
size_t token_count = guac_mem_ckd_add_or_die(guac_count_occurrences(string, delim), 1);
const char* token_start = string;
/* Allocate space for tokens */
char** tokens = malloc(sizeof(char*) * (token_count+1));
/* Allocate space for tokens, including NULL terminator */
char** tokens = guac_mem_alloc(sizeof(char*), guac_mem_ckd_add_or_die(token_count, 1));
do {
int length;
size_t length;
char* token;
/* Find end of token */
@ -66,7 +69,7 @@ char** guac_split(const char* string, char delim) {
length = string - token_start;
/* Allocate space for token and NULL terminator */
tokens[i++] = token = malloc(length + 1);
tokens[i++] = token = guac_mem_alloc(guac_mem_ckd_add_or_die(length, 1));
/* Copy token, store null */
memcpy(token, token_start, length);

View File

@ -24,6 +24,7 @@
#include <cairo/cairo.h>
#include <guacamole/client.h>
#include <guacamole/layer.h>
#include <guacamole/mem.h>
#include <guacamole/protocol.h>
#include <guacamole/socket.h>
#include <guacamole/timestamp.h>
@ -396,7 +397,7 @@ static unsigned int __guac_common_surface_calculate_framerate(
int x, y;
/* Calculate heat map dimensions */
int heat_width = GUAC_COMMON_SURFACE_HEAT_DIMENSION(surface->width);
size_t heat_width = GUAC_COMMON_SURFACE_HEAT_DIMENSION(surface->width);
/* Calculate minimum X/Y coordinates intersecting given rect */
int min_x = rect->x / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
@ -615,7 +616,7 @@ static void __guac_common_surface_touch_rect(guac_common_surface* surface,
int x, y;
/* Calculate heat map dimensions */
int heat_width = GUAC_COMMON_SURFACE_HEAT_DIMENSION(surface->width);
size_t heat_width = GUAC_COMMON_SURFACE_HEAT_DIMENSION(surface->width);
/* Calculate minimum X/Y coordinates intersecting given rect */
int min_x = rect->x / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
@ -1227,11 +1228,11 @@ guac_common_surface* guac_common_surface_alloc(guac_client* client,
guac_socket* socket, const guac_layer* layer, int w, int h) {
/* Calculate heat map dimensions */
int heat_width = GUAC_COMMON_SURFACE_HEAT_DIMENSION(w);
int heat_height = GUAC_COMMON_SURFACE_HEAT_DIMENSION(h);
size_t heat_width = GUAC_COMMON_SURFACE_HEAT_DIMENSION(w);
size_t heat_height = GUAC_COMMON_SURFACE_HEAT_DIMENSION(h);
/* Init surface */
guac_common_surface* surface = calloc(1, sizeof(guac_common_surface));
guac_common_surface* surface = guac_mem_zalloc(sizeof(guac_common_surface));
surface->client = client;
surface->socket = socket;
surface->layer = layer;
@ -1244,10 +1245,10 @@ guac_common_surface* guac_common_surface_alloc(guac_client* client,
/* Create corresponding Cairo surface */
surface->stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, w);
surface->buffer = calloc(h, surface->stride);
surface->buffer = guac_mem_zalloc(h, surface->stride);
/* Create corresponding heat map */
surface->heat_map = calloc(heat_width * heat_height,
surface->heat_map = guac_mem_zalloc(heat_width, heat_height,
sizeof(guac_common_surface_heat_cell));
/* Reset clipping rect */
@ -1274,9 +1275,9 @@ void guac_common_surface_free(guac_common_surface* surface) {
pthread_mutex_destroy(&surface->_lock);
free(surface->heat_map);
free(surface->buffer);
free(surface);
guac_mem_free(surface->heat_map);
guac_mem_free(surface->buffer);
guac_mem_free(surface);
}
@ -1299,8 +1300,8 @@ void guac_common_surface_resize(guac_common_surface* surface, int w, int h) {
int sy = 0;
/* Calculate heat map dimensions */
int heat_width = GUAC_COMMON_SURFACE_HEAT_DIMENSION(w);
int heat_height = GUAC_COMMON_SURFACE_HEAT_DIMENSION(h);
size_t heat_width = GUAC_COMMON_SURFACE_HEAT_DIMENSION(w);
size_t heat_height = GUAC_COMMON_SURFACE_HEAT_DIMENSION(h);
/* Copy old surface data */
old_buffer = surface->buffer;
@ -1311,7 +1312,7 @@ void guac_common_surface_resize(guac_common_surface* surface, int w, int h) {
surface->width = w;
surface->height = h;
surface->stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, w);
surface->buffer = calloc(h, surface->stride);
surface->buffer = guac_mem_zalloc(h, surface->stride);
__guac_common_bound_rect(surface, &surface->clip_rect, NULL, NULL);
/* Copy relevant old data */
@ -1319,11 +1320,11 @@ void guac_common_surface_resize(guac_common_surface* surface, int w, int h) {
__guac_common_surface_put(old_buffer, old_stride, &sx, &sy, surface, &old_rect, 1);
/* Free old data */
free(old_buffer);
guac_mem_free(old_buffer);
/* Allocate completely new heat map (can safely discard old stats) */
free(surface->heat_map);
surface->heat_map = calloc(heat_width * heat_height,
guac_mem_free(surface->heat_map);
surface->heat_map = guac_mem_alloc(heat_width, heat_height,
sizeof(guac_common_surface_heat_cell));
/* Resize dirty rect to fit new surface dimensions */

View File

@ -50,7 +50,8 @@ test_common_SOURCES = \
test_common_CFLAGS = \
-Werror -Wall -pedantic \
@COMMON_INCLUDE@
@COMMON_INCLUDE@ \
@LIBGUAC_INCLUDE@
test_common_LDADD = \
@COMMON_LTLIB@ \

View File

@ -20,6 +20,7 @@
#include "common/string.h"
#include <CUnit/CUnit.h>
#include <guacamole/mem.h>
#include <stdlib.h>
@ -52,12 +53,12 @@ void test_string__split() {
CU_ASSERT_PTR_NULL(tokens[5]);
/* Clean up */
free(tokens[0]);
free(tokens[1]);
free(tokens[2]);
free(tokens[3]);
free(tokens[4]);
free(tokens);
guac_mem_free(tokens[0]);
guac_mem_free(tokens[1]);
guac_mem_free(tokens[2]);
guac_mem_free(tokens[3]);
guac_mem_free(tokens[4]);
guac_mem_free(tokens);
}

View File

@ -23,6 +23,9 @@
#include "conf-args.h"
#include "conf-parse.h"
#include <guacamole/mem.h>
#include <guacamole/string.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
@ -36,14 +39,14 @@ int guacd_conf_parse_args(guacd_config* config, int argc, char** argv) {
/* -l: Bind port */
if (opt == 'l') {
free(config->bind_port);
config->bind_port = strdup(optarg);
guac_mem_free(config->bind_port);
config->bind_port = guac_strdup(optarg);
}
/* -b: Bind host */
else if (opt == 'b') {
free(config->bind_host);
config->bind_host = strdup(optarg);
guac_mem_free(config->bind_host);
config->bind_host = guac_strdup(optarg);
}
/* -f: Run in foreground */
@ -58,8 +61,8 @@ int guacd_conf_parse_args(guacd_config* config, int argc, char** argv) {
/* -p: PID file */
else if (opt == 'p') {
free(config->pidfile);
config->pidfile = strdup(optarg);
guac_mem_free(config->pidfile);
config->pidfile = guac_strdup(optarg);
}
/* -L: Log level */
@ -79,14 +82,14 @@ int guacd_conf_parse_args(guacd_config* config, int argc, char** argv) {
#ifdef ENABLE_SSL
/* -C SSL certificate */
else if (opt == 'C') {
free(config->cert_file);
config->cert_file = strdup(optarg);
guac_mem_free(config->cert_file);
config->cert_file = guac_strdup(optarg);
}
/* -K SSL key */
else if (opt == 'K') {
free(config->key_file);
config->key_file = strdup(optarg);
guac_mem_free(config->key_file);
config->key_file = guac_strdup(optarg);
}
#else
else if (opt == 'C' || opt == 'K') {

View File

@ -24,6 +24,8 @@
#include "conf-parse.h"
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <guacamole/string.h>
#include <errno.h>
#include <stdio.h>
@ -48,15 +50,15 @@ static int guacd_conf_callback(const char* section, const char* param, const cha
/* Bind host */
if (strcmp(param, "bind_host") == 0) {
free(config->bind_host);
config->bind_host = strdup(value);
guac_mem_free(config->bind_host);
config->bind_host = guac_strdup(value);
return 0;
}
/* Bind port */
else if (strcmp(param, "bind_port") == 0) {
free(config->bind_port);
config->bind_port = strdup(value);
guac_mem_free(config->bind_port);
config->bind_port = guac_strdup(value);
return 0;
}
@ -67,8 +69,8 @@ static int guacd_conf_callback(const char* section, const char* param, const cha
/* PID file */
if (strcmp(param, "pid_file") == 0) {
free(config->pidfile);
config->pidfile = strdup(value);
guac_mem_free(config->pidfile);
config->pidfile = guac_strdup(value);
return 0;
}
@ -96,15 +98,15 @@ static int guacd_conf_callback(const char* section, const char* param, const cha
#ifdef ENABLE_SSL
/* SSL certificate */
if (strcmp(param, "server_certificate") == 0) {
free(config->cert_file);
config->cert_file = strdup(value);
guac_mem_free(config->cert_file);
config->cert_file = guac_strdup(value);
return 0;
}
/* SSL key */
else if (strcmp(param, "server_key") == 0) {
free(config->key_file);
config->key_file = strdup(value);
guac_mem_free(config->key_file);
config->key_file = guac_strdup(value);
return 0;
}
#else
@ -171,13 +173,13 @@ int guacd_conf_parse_file(guacd_config* conf, int fd) {
guacd_config* guacd_conf_load() {
guacd_config* conf = malloc(sizeof(guacd_config));
guacd_config* conf = guac_mem_alloc(sizeof(guacd_config));
if (conf == NULL)
return NULL;
/* Load defaults */
conf->bind_host = strdup(GUACD_DEFAULT_BIND_HOST);
conf->bind_port = strdup(GUACD_DEFAULT_BIND_PORT);
conf->bind_host = guac_strdup(GUACD_DEFAULT_BIND_HOST);
conf->bind_port = guac_strdup(GUACD_DEFAULT_BIND_PORT);
conf->pidfile = NULL;
conf->foreground = 0;
conf->print_version = 0;
@ -197,7 +199,7 @@ guacd_config* guacd_conf_load() {
if (retval != 0) {
fprintf(stderr, "Unable to parse \"" GUACD_CONF_FILE "\".\n");
free(conf);
guac_mem_free(conf);
return NULL;
}
@ -206,7 +208,7 @@ guacd_config* guacd_conf_load() {
/* Notify of errors preventing reading */
else if (errno != ENOENT) {
fprintf(stderr, "Unable to open \"" GUACD_CONF_FILE "\": %s\n", strerror(errno));
free(conf);
guac_mem_free(conf);
return NULL;
}

View File

@ -27,6 +27,7 @@
#include <guacamole/client.h>
#include <guacamole/error.h>
#include <guacamole/mem.h>
#include <guacamole/parser.h>
#include <guacamole/plugin.h>
#include <guacamole/protocol.h>
@ -151,7 +152,7 @@ void* guacd_connection_io_thread(void* data) {
/* Clean up */
guac_socket_free(params->socket);
close(params->fd);
free(params);
guac_mem_free(params);
return NULL;
@ -202,7 +203,7 @@ static int guacd_add_user(guacd_proc* proc, guac_parser* parser, guac_socket* so
/* Close our end of the process file descriptor */
close(proc_fd);
guacd_connection_io_thread_params* params = malloc(sizeof(guacd_connection_io_thread_params));
guacd_connection_io_thread_params* params = guac_mem_alloc(sizeof(guacd_connection_io_thread_params));
params->parser = parser;
params->socket = socket;
params->fd = user_fd;
@ -353,7 +354,7 @@ static int guacd_route_connection(guacd_proc_map* map, guac_socket* socket) {
/* Clean up */
close(proc->fd_socket);
free(proc);
guac_mem_free(proc);
}
@ -381,7 +382,7 @@ void* guacd_connection_thread(void* data) {
if (socket == NULL) {
guacd_log_guac_error(GUAC_LOG_ERROR, "Unable to set up SSL/TLS");
close(connected_socket_fd);
free(params);
guac_mem_free(params);
return NULL;
}
}
@ -397,7 +398,7 @@ void* guacd_connection_thread(void* data) {
if (guacd_route_connection(map, socket))
guac_socket_free(socket);
free(params);
guac_mem_free(params);
return NULL;
}

View File

@ -26,6 +26,8 @@
#include "log.h"
#include "proc-map.h"
#include <guacamole/mem.h>
#ifdef ENABLE_SSL
#include <openssl/ssl.h>
#endif
@ -212,8 +214,7 @@ static void guacd_openssl_init_locks(int count) {
int i;
/* Allocate required number of locks */
guacd_openssl_locks =
malloc(sizeof(pthread_mutex_t) * count);
guacd_openssl_locks = guac_mem_alloc(sizeof(pthread_mutex_t), count);
/* Initialize each lock */
for (i=0; i < count; i++)
@ -240,7 +241,7 @@ static void guacd_openssl_free_locks(int count) {
pthread_mutex_destroy(&(guacd_openssl_locks[i]));
/* Free lock array */
free(guacd_openssl_locks);
guac_mem_free(guacd_openssl_locks);
}
#endif
@ -532,7 +533,7 @@ int main(int argc, char* argv[]) {
}
/* Create parameters for connection thread */
guacd_connection_thread_params* params = malloc(sizeof(guacd_connection_thread_params));
guacd_connection_thread_params* params = guac_mem_alloc(sizeof(guacd_connection_thread_params));
if (params == NULL) {
guacd_log(GUAC_LOG_ERROR, "Could not create connection thread: %s", strerror(errno));
continue;

View File

@ -23,6 +23,7 @@
#include "proc-map.h"
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <stdlib.h>
#include <string.h>
@ -129,7 +130,7 @@ static guac_common_list_element* __guacd_proc_find(guac_common_list* bucket,
guacd_proc_map* guacd_proc_map_alloc() {
guacd_proc_map* map = malloc(sizeof(guacd_proc_map));
guacd_proc_map* map = guac_mem_alloc(sizeof(guacd_proc_map));
map->processes = guac_common_list_alloc();
guac_common_list** current;
@ -160,7 +161,7 @@ int guacd_proc_map_add(guacd_proc_map* map, guacd_proc* proc) {
/* If no such element, we can add the new client successfully */
if (found == NULL) {
guacd_proc_map_entry* entry = malloc(sizeof(guacd_proc_map_entry));
guacd_proc_map_entry* entry = guac_mem_alloc(sizeof(guacd_proc_map_entry));
guac_common_list_lock(map->processes);
entry->element = guac_common_list_add(map->processes, proc);

View File

@ -26,6 +26,7 @@
#include <guacamole/client.h>
#include <guacamole/error.h>
#include <guacamole/mem.h>
#include <guacamole/parser.h>
#include <guacamole/plugin.h>
#include <guacamole/protocol.h>
@ -106,7 +107,7 @@ static void* guacd_user_thread(void* data) {
/* Clean up */
guac_socket_free(socket);
guac_user_free(user);
free(params);
guac_mem_free(params);
return NULL;
@ -130,7 +131,7 @@ static void* guacd_user_thread(void* data) {
*/
static void guacd_proc_add_user(guacd_proc* proc, int fd, int owner) {
guacd_user_thread_params* params = malloc(sizeof(guacd_user_thread_params));
guacd_user_thread_params* params = guac_mem_alloc(sizeof(guacd_user_thread_params));
params->proc = proc;
params->fd = fd;
params->owner = owner;
@ -409,7 +410,7 @@ cleanup_process:
/* Free up all internal resources outside the client */
close(proc->fd_socket);
free(proc);
guac_mem_free(proc);
exit(result);
@ -429,7 +430,7 @@ guacd_proc* guacd_create_proc(const char* protocol) {
int child_socket = sockets[1];
/* Allocate process */
guacd_proc* proc = calloc(1, sizeof(guacd_proc));
guacd_proc* proc = guac_mem_zalloc(sizeof(guacd_proc));
if (proc == NULL) {
close(parent_socket);
close(child_socket);
@ -442,7 +443,7 @@ guacd_proc* guacd_create_proc(const char* protocol) {
guacd_log_guac_error(GUAC_LOG_ERROR, "Unable to create client");
close(parent_socket);
close(child_socket);
free(proc);
guac_mem_free(proc);
return NULL;
}
@ -456,7 +457,7 @@ guacd_proc* guacd_create_proc(const char* protocol) {
close(parent_socket);
close(child_socket);
guac_client_free(proc->client);
free(proc);
guac_mem_free(proc);
return NULL;
}

View File

@ -21,12 +21,13 @@
#include "buffer.h"
#include <cairo/cairo.h>
#include <guacamole/mem.h>
#include <assert.h>
#include <stdlib.h>
guacenc_buffer* guacenc_buffer_alloc() {
return calloc(1, sizeof(guacenc_buffer));
return guac_mem_zalloc(sizeof(guacenc_buffer));
}
/**
@ -52,7 +53,7 @@ static void guacenc_buffer_free_image(guacenc_buffer* buffer) {
}
/* Free image data (previously wrapped by Cairo surface */
free(buffer->image);
guac_mem_free(buffer->image);
buffer->image = NULL;
}
@ -65,7 +66,7 @@ void guacenc_buffer_free(guacenc_buffer* buffer) {
/* Free buffer and underlying image */
guacenc_buffer_free_image(buffer);
free(buffer);
guac_mem_free(buffer);
}
@ -86,7 +87,7 @@ int guacenc_buffer_resize(guacenc_buffer* buffer, int width, int height) {
/* Allocate data for new image */
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
unsigned char* image = calloc(1, stride*height);
unsigned char* image = guac_mem_zalloc(stride, height);
/* Wrap data in surface */
cairo_surface_t* surface = cairo_image_surface_create_for_data(image,

View File

@ -21,19 +21,21 @@
#include "buffer.h"
#include "cursor.h"
#include <guacamole/mem.h>
#include <stdlib.h>
guacenc_cursor* guacenc_cursor_alloc() {
/* Allocate new cursor */
guacenc_cursor* cursor = (guacenc_cursor*) malloc(sizeof(guacenc_cursor));
guacenc_cursor* cursor = (guacenc_cursor*) guac_mem_alloc(sizeof(guacenc_cursor));
if (cursor == NULL)
return NULL;
/* Allocate associated buffer (image) */
cursor->buffer = guacenc_buffer_alloc();
if (cursor->buffer == NULL) {
free(cursor);
guac_mem_free(cursor);
return NULL;
}
@ -53,7 +55,7 @@ void guacenc_cursor_free(guacenc_cursor* cursor) {
/* Free underlying buffer */
guacenc_buffer_free(cursor->buffer);
free(cursor);
guac_mem_free(cursor);
}

View File

@ -23,6 +23,7 @@
#include "video.h"
#include <cairo/cairo.h>
#include <guacamole/mem.h>
#include <stdlib.h>
@ -93,7 +94,7 @@ guacenc_display* guacenc_display_alloc(const char* path, const char* codec,
/* Allocate display */
guacenc_display* display =
(guacenc_display*) calloc(1, sizeof(guacenc_display));
(guacenc_display*) guac_mem_zalloc(sizeof(guacenc_display));
/* Associate display with video output */
display->output = video;
@ -131,7 +132,7 @@ int guacenc_display_free(guacenc_display* display) {
/* Free cursor */
guacenc_cursor_free(display->cursor);
free(display);
guac_mem_free(display);
return retval;
}

View File

@ -26,6 +26,7 @@
#include <libavutil/common.h>
#include <libavutil/imgutils.h>
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <stdio.h>
#include <stdint.h>
@ -106,10 +107,11 @@ int guacenc_avcodec_encode_video(guacenc_video* video, AVFrame* frame) {
AVCodecContext* context = video->context;
/* Calculate appropriate buffer size */
int length = FF_MIN_BUFFER_SIZE + 12 * context->width * context->height;
size_t length = guac_mem_ckd_add_or_die(FF_MIN_BUFFER_SIZE,
guac_mem_ckd_mul_or_die(12, context->width, context->height));
/* Allocate space for output */
uint8_t* data = malloc(length);
uint8_t* data = guac_mem_alloc(length);
if (data == NULL)
return -1;
@ -118,19 +120,19 @@ int guacenc_avcodec_encode_video(guacenc_video* video, AVFrame* frame) {
if (used < 0) {
guacenc_log(GUAC_LOG_WARNING, "Error encoding frame #%" PRId64,
video->next_pts);
free(data);
guac_mem_free(data);
return -1;
}
/* Report if no data needs to be written */
if (used == 0) {
free(data);
guac_mem_free(data);
return 0;
}
/* Write data, logging any errors */
guacenc_write_packet(video, data, used);
free(data);
guac_mem_free(data);
return 1;
#else

View File

@ -29,6 +29,7 @@
#endif
#include <cairo/cairo.h>
#include <guacamole/mem.h>
#include <stdlib.h>
#include <string.h>
@ -67,7 +68,7 @@ guacenc_image_stream* guacenc_image_stream_alloc(int mask, int index,
const char* mimetype, int x, int y) {
/* Allocate stream */
guacenc_image_stream* stream = malloc(sizeof(guacenc_image_stream));
guacenc_image_stream* stream = guac_mem_alloc(sizeof(guacenc_image_stream));
if (stream == NULL)
return NULL;
@ -83,7 +84,7 @@ guacenc_image_stream* guacenc_image_stream_alloc(int mask, int index,
/* Allocate initial buffer */
stream->length = 0;
stream->max_length = GUACENC_IMAGE_STREAM_INITIAL_LENGTH;
stream->buffer = (unsigned char*) malloc(stream->max_length);
stream->buffer = (unsigned char*) guac_mem_alloc(stream->max_length);
return stream;
@ -96,11 +97,12 @@ int guacenc_image_stream_receive(guacenc_image_stream* stream,
if (stream->max_length - stream->length < length) {
/* Calculate a reasonable new max length guaranteed to fit buffer */
int new_max_length = stream->max_length * 2 + length;
size_t new_max_length = guac_mem_ckd_add_or_die(
guac_mem_ckd_mul_or_die(stream->max_length, 2), length);
/* Attempt to resize buffer */
unsigned char* new_buffer =
(unsigned char*) realloc(stream->buffer, new_max_length);
(unsigned char*) guac_mem_realloc(stream->buffer, new_max_length);
if (new_buffer == NULL)
return 1;
@ -158,10 +160,10 @@ int guacenc_image_stream_free(guacenc_image_stream* stream) {
return 0;
/* Free image buffer */
free(stream->buffer);
guac_mem_free(stream->buffer);
/* Free actual stream */
free(stream);
guac_mem_free(stream);
return 0;
}

View File

@ -25,6 +25,8 @@
#include <cairo/cairo.h>
#include <stddef.h>
/**
* The initial number of bytes to allocate for the image data buffer. If this
* buffer is not sufficiently large, it will be dynamically reallocated as it
@ -87,13 +89,13 @@ typedef struct guacenc_image_stream {
/**
* The number of bytes currently stored in the buffer.
*/
int length;
size_t length;
/**
* The maximum number of bytes that can be stored in the current buffer
* before it must be reallocated.
*/
int max_length;
size_t max_length;
/**
* The decoder to use when decoding the raw data received along this

View File

@ -25,6 +25,7 @@
#include <unistd.h>
#include <cairo/cairo.h>
#include <guacamole/mem.h>
#include <jpeglib.h>
#include <stdlib.h>
@ -109,7 +110,7 @@ cairo_surface_t* guacenc_jpeg_decoder(unsigned char* data, int length) {
int height = cinfo.output_height;
/* Allocate sufficient buffer space for one JPEG scanline */
unsigned char* jpeg_scanline = malloc(width * 3);
unsigned char* jpeg_scanline = guac_mem_alloc(width, 3);
/* Create blank Cairo surface (no transparency in JPEG) */
cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
@ -135,7 +136,7 @@ cairo_surface_t* guacenc_jpeg_decoder(unsigned char* data, int length) {
}
/* Scanline buffer is no longer needed */
free(jpeg_scanline);
guac_mem_free(jpeg_scanline);
/* End decompression */
jpeg_finish_decompress(&cinfo);

View File

@ -21,19 +21,21 @@
#include "buffer.h"
#include "layer.h"
#include <guacamole/mem.h>
#include <stdlib.h>
guacenc_layer* guacenc_layer_alloc() {
/* Allocate new layer */
guacenc_layer* layer = (guacenc_layer*) calloc(1, sizeof(guacenc_layer));
guacenc_layer* layer = (guacenc_layer*) guac_mem_zalloc(sizeof(guacenc_layer));
if (layer == NULL)
return NULL;
/* Allocate associated buffer (width, height, and image storage) */
layer->buffer = guacenc_buffer_alloc();
if (layer->buffer == NULL) {
free(layer);
guac_mem_free(layer);
return NULL;
}
@ -41,7 +43,7 @@ guacenc_layer* guacenc_layer_alloc() {
layer->frame = guacenc_buffer_alloc();
if (layer->frame== NULL) {
guacenc_buffer_free(layer->buffer);
free(layer);
guac_mem_free(layer);
return NULL;
}
@ -67,7 +69,7 @@ void guacenc_layer_free(guacenc_layer* layer) {
/* Free underlying buffer */
guacenc_buffer_free(layer->buffer);
free(layer);
guac_mem_free(layer);
}

View File

@ -32,6 +32,7 @@
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <guacamole/timestamp.h>
#include <sys/types.h>
@ -138,7 +139,7 @@ guacenc_video* guacenc_video_alloc(const char* path, const char* codec_name,
}
/* Allocate video structure */
guacenc_video* video = malloc(sizeof(guacenc_video));
guacenc_video* video = guac_mem_alloc(sizeof(guacenc_video));
if (video == NULL)
goto fail_alloc_video;
@ -503,7 +504,7 @@ int guacenc_video_free(guacenc_video* video) {
avcodec_free_context(&(video->context));
}
free(video);
guac_mem_free(video);
return 0;
}

View File

@ -21,6 +21,9 @@
#include "keydef.h"
#include "log.h"
#include <guacamole/mem.h>
#include <guacamole/string.h>
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
@ -279,16 +282,16 @@ static guaclog_keydef* guaclog_get_unicode_key(int keysym) {
*/
static guaclog_keydef* guaclog_copy_key(guaclog_keydef* keydef) {
guaclog_keydef* copy = malloc(sizeof(guaclog_keydef));
guaclog_keydef* copy = guac_mem_alloc(sizeof(guaclog_keydef));
/* Always copy keysym and name */
copy->keysym = keydef->keysym;
copy->name = strdup(keydef->name);
copy->name = guac_strdup(keydef->name);
copy->modifier = keydef->modifier;
/* Copy value only if defined */
if (keydef->value != NULL)
copy->value = strdup(keydef->value);
copy->value = guac_strdup(keydef->value);
else
copy->value = NULL;
@ -322,9 +325,9 @@ void guaclog_keydef_free(guaclog_keydef* keydef) {
if (keydef == NULL)
return;
free(keydef->name);
free(keydef->value);
free(keydef);
guac_mem_free(keydef->name);
guac_mem_free(keydef->value);
guac_mem_free(keydef);
}

View File

@ -22,6 +22,9 @@
#include "log.h"
#include "state.h"
#include <guacamole/mem.h>
#include <guacamole/string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
@ -50,7 +53,7 @@ guaclog_state* guaclog_state_alloc(const char* path) {
}
/* Allocate state */
guaclog_state* state = (guaclog_state*) calloc(1, sizeof(guaclog_state));
guaclog_state* state = (guaclog_state*) guac_mem_zalloc(sizeof(guaclog_state));
if (state == NULL) {
goto fail_state;
}
@ -90,7 +93,7 @@ int guaclog_state_free(guaclog_state* state) {
/* Close output file */
fclose(state->output);
free(state);
guac_mem_free(state);
return 0;
}

View File

@ -29,6 +29,10 @@ ACLOCAL_AMFLAGS = -I m4
lib_LTLIBRARIES = libguac.la
SUBDIRS = . tests
#
# Public headers
#
libguacincdir = $(includedir)/guacamole
libguacinc_HEADERS = \
@ -48,6 +52,7 @@ libguacinc_HEADERS = \
guacamole/hash.h \
guacamole/layer.h \
guacamole/layer-types.h \
guacamole/mem.h \
guacamole/object.h \
guacamole/object-types.h \
guacamole/parser-constants.h \
@ -79,6 +84,19 @@ libguacinc_HEADERS = \
guacamole/wol.h \
guacamole/wol-constants.h
#
# Private, installed headers
#
libguacprivincdir = $(includedir)/guacamole/private
libguacprivinc_HEADERS = \
guacamole/private/mem.h
#
# Private, non-installed headers
#
noinst_HEADERS = \
id.h \
encode-jpeg.h \
@ -98,6 +116,7 @@ libguac_la_SOURCES = \
fips.c \
hash.c \
id.c \
mem.c \
rwlock.c \
palette.c \
parser.c \

View File

@ -19,6 +19,7 @@
#include "config.h"
#include "guacamole/mem.h"
#include "guacamole/argv.h"
#include "guacamole/client.h"
#include "guacamole/protocol.h"
@ -273,7 +274,7 @@ static int guac_argv_end_handler(guac_user* user, guac_stream* stream) {
pthread_mutex_unlock(&await_state.lock);
free(argv);
guac_mem_free(argv);
return 0;
}
@ -293,7 +294,7 @@ int guac_argv_received(guac_stream* stream, const char* mimetype, const char* na
/* Argument matched */
if (strcmp(state->name, name) == 0) {
guac_argv* argv = malloc(sizeof(guac_argv));
guac_argv* argv = guac_mem_alloc(sizeof(guac_argv));
guac_strlcpy(argv->mimetype, mimetype, sizeof(argv->mimetype));
argv->state = state;
argv->length = 0;

View File

@ -19,6 +19,7 @@
#include "config.h"
#include "guacamole/mem.h"
#include "guacamole/audio.h"
#include "guacamole/client.h"
#include "guacamole/protocol.h"
@ -113,13 +114,13 @@ guac_audio_stream* guac_audio_stream_alloc(guac_client* client,
guac_audio_stream* audio;
/* Allocate stream */
audio = (guac_audio_stream*) calloc(1, sizeof(guac_audio_stream));
audio = (guac_audio_stream*) guac_mem_zalloc(sizeof(guac_audio_stream));
audio->client = client;
audio->stream = guac_client_alloc_stream(client);
/* Abort allocation if underlying stream cannot be allocated */
if (audio->stream == NULL) {
free(audio);
guac_mem_free(audio);
return NULL;
}
@ -198,7 +199,7 @@ void guac_audio_stream_free(guac_audio_stream* audio) {
guac_client_free_stream(audio->client, audio->stream);
/* Free associated data */
free(audio);
guac_mem_free(audio);
}

View File

@ -22,6 +22,7 @@
#include "encode-jpeg.h"
#include "encode-png.h"
#include "encode-webp.h"
#include "guacamole/mem.h"
#include "guacamole/client.h"
#include "guacamole/error.h"
#include "guacamole/layer.h"
@ -84,7 +85,7 @@ const guac_layer* GUAC_DEFAULT_LAYER = &__GUAC_DEFAULT_LAYER;
guac_layer* guac_client_alloc_layer(guac_client* client) {
/* Init new layer */
guac_layer* allocd_layer = malloc(sizeof(guac_layer));
guac_layer* allocd_layer = guac_mem_alloc(sizeof(guac_layer));
allocd_layer->index = guac_pool_next_int(client->__layer_pool)+1;
return allocd_layer;
@ -94,7 +95,7 @@ guac_layer* guac_client_alloc_layer(guac_client* client) {
guac_layer* guac_client_alloc_buffer(guac_client* client) {
/* Init new layer */
guac_layer* allocd_layer = malloc(sizeof(guac_layer));
guac_layer* allocd_layer = guac_mem_alloc(sizeof(guac_layer));
allocd_layer->index = -guac_pool_next_int(client->__buffer_pool) - 1;
return allocd_layer;
@ -107,7 +108,7 @@ void guac_client_free_buffer(guac_client* client, guac_layer* layer) {
guac_pool_free_int(client->__buffer_pool, -layer->index - 1);
/* Free layer */
free(layer);
guac_mem_free(layer);
}
@ -117,7 +118,7 @@ void guac_client_free_layer(guac_client* client, guac_layer* layer) {
guac_pool_free_int(client->__layer_pool, layer->index);
/* Free layer */
free(layer);
guac_mem_free(layer);
}
@ -255,7 +256,7 @@ guac_client* guac_client_alloc() {
int i;
/* Allocate new client */
guac_client* client = malloc(sizeof(guac_client));
guac_client* client = guac_mem_alloc(sizeof(guac_client));
if (client == NULL) {
guac_error = GUAC_STATUS_NO_MEMORY;
guac_error_message = "Could not allocate memory for client";
@ -272,7 +273,7 @@ guac_client* guac_client_alloc() {
/* Generate ID */
client->connection_id = guac_generate_id(GUAC_CLIENT_ID_PREFIX);
if (client->connection_id == NULL) {
free(client);
guac_mem_free(client);
return NULL;
}
@ -284,7 +285,7 @@ guac_client* guac_client_alloc() {
client->__stream_pool = guac_pool_alloc(0);
/* Initialize streams */
client->__output_streams = malloc(sizeof(guac_stream) * GUAC_CLIENT_MAX_STREAMS);
client->__output_streams = guac_mem_alloc(sizeof(guac_stream), GUAC_CLIENT_MAX_STREAMS);
for (i=0; i<GUAC_CLIENT_MAX_STREAMS; i++) {
client->__output_streams[i].index = GUAC_CLIENT_CLOSED_STREAM_INDEX;
@ -346,7 +347,7 @@ void guac_client_free(guac_client* client) {
guac_pool_free(client->__layer_pool);
/* Free streams */
free(client->__output_streams);
guac_mem_free(client->__output_streams);
/* Free stream pool */
guac_pool_free(client->__stream_pool);
@ -374,8 +375,8 @@ void guac_client_free(guac_client* client) {
guac_rwlock_destroy(&(client->__users_lock));
guac_rwlock_destroy(&(client->__pending_users_lock));
free(client->connection_id);
free(client);
guac_mem_free(client->connection_id);
guac_mem_free(client);
}
void vguac_client_log(guac_client* client, guac_client_log_level level,

View File

@ -20,6 +20,7 @@
#include "config.h"
#include "encode-jpeg.h"
#include "guacamole/mem.h"
#include "guacamole/error.h"
#include "guacamole/protocol.h"
#include "guacamole/stream.h"
@ -211,9 +212,7 @@ int guac_jpeg_write(guac_socket* socket, guac_stream* stream,
/* Create a buffer for the write scan line which is where we will
* put the converted pixels (BGRx -> RGB) */
int write_stride = cinfo.image_width * cinfo.input_components;
unsigned char *scanline_data = malloc(write_stride);
memset(scanline_data, 0, write_stride);
unsigned char *scanline_data = guac_mem_zalloc(cinfo.image_width, cinfo.input_components);
#endif
/* Initialize the JPEG compressor */
@ -254,7 +253,7 @@ int guac_jpeg_write(guac_socket* socket, guac_stream* stream,
}
#ifndef JCS_EXTENSIONS
free(scanline_data);
guac_mem_free(scanline_data);
#endif
/* Finalize compression */

View File

@ -20,6 +20,7 @@
#include "config.h"
#include "encode-png.h"
#include "guacamole/mem.h"
#include "guacamole/error.h"
#include "guacamole/protocol.h"
#include "guacamole/stream.h"
@ -342,11 +343,11 @@ int guac_png_write(guac_socket* socket, guac_stream* stream,
guac_png_flush_handler);
/* Copy data from surface into PNG data */
png_rows = (png_byte**) malloc(sizeof(png_byte*) * height);
png_rows = (png_byte**) guac_mem_alloc(sizeof(png_byte*), height);
for (y=0; y<height; y++) {
/* Allocate new PNG row */
png_byte* row = (png_byte*) malloc(sizeof(png_byte) * width);
png_byte* row = (png_byte*) guac_mem_alloc(sizeof(png_byte), width);
png_rows[y] = row;
/* Copy data from surface into current row */
@ -393,8 +394,8 @@ int guac_png_write(guac_socket* socket, guac_stream* stream,
/* Free PNG data */
for (y=0; y<height; y++)
free(png_rows[y]);
free(png_rows);
guac_mem_free(png_rows[y]);
guac_mem_free(png_rows);
/* Ensure all data is written */
guac_png_flush_data(&write_state);

View File

@ -19,6 +19,7 @@
#include "config.h"
#include "guacamole/mem.h"
#include "guacamole/error.h"
#include <errno.h>
@ -176,24 +177,24 @@ static pthread_once_t __guac_error_key_init = PTHREAD_ONCE_INIT;
static pthread_key_t __guac_error_message_key;
static pthread_once_t __guac_error_message_key_init = PTHREAD_ONCE_INIT;
static void __guac_free_pointer(void* pointer) {
static void __guac_mem_free_pointer(void* pointer) {
/* Free memory allocated to status variable */
free(pointer);
guac_mem_free(pointer);
}
static void __guac_alloc_error_key() {
/* Create key, destroy any allocated variable on thread exit */
pthread_key_create(&__guac_error_key, __guac_free_pointer);
pthread_key_create(&__guac_error_key, __guac_mem_free_pointer);
}
static void __guac_alloc_error_message_key() {
/* Create key, destroy any allocated variable on thread exit */
pthread_key_create(&__guac_error_message_key, __guac_free_pointer);
pthread_key_create(&__guac_error_message_key, __guac_mem_free_pointer);
}
@ -210,7 +211,7 @@ guac_status* __guac_error() {
/* Allocate thread-local status variable if not already allocated */
if (status == NULL) {
status = malloc(sizeof(guac_status));
status = guac_mem_alloc(sizeof(guac_status));
pthread_setspecific(__guac_error_key, status);
}
@ -234,7 +235,7 @@ const char** __guac_error_message() {
/* Allocate thread-local message variable if not already allocated */
if (message == NULL) {
message = malloc(sizeof(const char*));
message = guac_mem_alloc(sizeof(const char*));
pthread_setspecific(__guac_error_message_key, message);
}

413
src/libguac/guacamole/mem.h Normal file
View File

@ -0,0 +1,413 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef GUAC_MEM_H
#define GUAC_MEM_H
/**
* Provides convenience macros/functions for performing arithmetic on size_t
* values and for allocating memory, particularly memory related to images,
* audio, etc. where there are multiple factors affecting the final size.
*
* @file mem.h
*/
#include "private/mem.h"
#include <stddef.h>
/**
* Allocates a contiguous block of memory with the specified size, returning a
* pointer to the first byte of that block of memory. If multiple sizes are
* provided, these sizes are multiplied together to produce the final size of
* the new block. If memory of the specified size cannot be allocated, or if
* multiplying the sizes would result in integer overflow, guac_error is set
* appropriately and NULL is returned.
*
* This macro is analogous to the standard malloc(), but accepts a list of size
* factors instead of a single integer size.
*
* The pointer returned by guac_mem_alloc() SHOULD be freed with a subsequent call
* to guac_mem_free(), but MAY instead be freed with a subsequent call to free().
*
* @param ...
* A series of one or more size_t values that should be multiplied together
* to produce the desired block size. At least one value MUST be provided.
*
* @returns
* A pointer to the first byte of the allocated block of memory, or NULL if
* such a block could not be allocated. If a block of memory could not be
* allocated, guac_error is set appropriately.
*/
#define guac_mem_alloc(...) \
PRIV_guac_mem_alloc( \
sizeof((const size_t[]) { __VA_ARGS__ }) / sizeof(const size_t), \
(const size_t[]) { __VA_ARGS__ } \
)
/**
* Allocates a contiguous block of memory with the specified size and with all
* bytes initialized to zero, returning a pointer to the first byte of that
* block of memory. If multiple sizes are provided, these sizes are multiplied
* together to produce the final size of the new block. If memory of the
* specified size cannot be allocated, or if multiplying the sizes would result
* in integer overflow, guac_error is set appropriately and NULL is returned.
*
* This macro is analogous to the standard calloc(), but accepts a list of size
* factors instead of a requiring exactly two integer sizes.
*
* The pointer returned by guac_mem_zalloc() SHOULD be freed with a subsequent call
* to guac_mem_free(), but MAY instead be freed with a subsequent call to free().
*
* @param ...
* A series of one or more size_t values that should be multiplied together
* to produce the desired block size. At least one value MUST be provided.
*
* @returns
* A pointer to the first byte of the allocated block of memory, or NULL if
* such a block could not be allocated. If a block of memory could not be
* allocated, guac_error is set appropriately.
*/
#define guac_mem_zalloc(...) \
PRIV_guac_mem_zalloc( \
sizeof((const size_t[]) { __VA_ARGS__ }) / sizeof(const size_t), \
(const size_t[]) { __VA_ARGS__ } \
)
/**
* Multiplies together each of the given values, storing the result in a size_t
* variable via the provided pointer. If the result of the multiplication
* overflows the limits of a size_t, non-zero is returned to signal failure.
*
* If the multiplication operation fails, the nature of any result stored in
* the provided pointer is undefined, as is whether a result is stored at all.
*
* For example, the following:
* @code
* size_t some_result;
* int failed = guac_mem_ckd_mul(&some_result, a, b, c);
* @endcode
*
* is equivalent in principle to:
* @code
* size_t some_result = a * b * c;
* @endcode
*
* except that it is possible for interested callers to handle overflow.
*
* @param result
* A pointer to the size_t variable that should receive the result of
* multiplying the given values.
*
* @param ...
* The size_t values that should be multiplied together.
*
* @returns
* Zero if the multiplication was successful and did not overflow the
* limits of a size_t, non-zero otherwise.
*/
#define guac_mem_ckd_mul(result, ...) \
PRIV_guac_mem_ckd_mul( \
result, \
sizeof((const size_t[]) { __VA_ARGS__ }) / sizeof(const size_t), \
(const size_t[]) { __VA_ARGS__ } \
)
/**
* Adds together each of the given values, storing the result in a size_t
* variable via the provided pointer. If the result of the addition overflows
* the limits of a size_t, non-zero is returned to signal failure.
*
* If the addition operation fails, the nature of any result stored in the
* provided pointer is undefined, as is whether a result is stored at all.
*
* For example, the following:
* @code
* size_t some_result;
* int failed = guac_mem_ckd_add(&some_result, a, b, c);
* @endcode
*
* is equivalent in principle to:
* @code
* size_t some_result = a + b + c;
* @endcode
*
* except that it is possible for interested callers to handle overflow.
*
* @param result
* A pointer to the size_t variable that should receive the result of
* adding the given values.
*
* @param ...
* The size_t values that should be added together.
*
* @returns
* Zero if the addition was successful and did not overflow the limits of a
* size_t, non-zero otherwise.
*/
#define guac_mem_ckd_add(result, ...) \
PRIV_guac_mem_ckd_add( \
result, \
sizeof((const size_t[]) { __VA_ARGS__ }) / sizeof(const size_t), \
(const size_t[]) { __VA_ARGS__ } \
)
/**
* Subtracts each of the given values from each other, storing the result in a
* size_t variable via the provided pointer. If the result of the subtraction
* overflows the limits of a size_t (goes below zero), non-zero is returned to
* signal failure.
*
* If the subtraction operation fails, the nature of any result stored in the
* provided pointer is undefined, as is whether a result is stored at all.
*
* For example, the following:
* @code
* size_t some_result;
* int failed = guac_mem_ckd_sub(&some_result, a, b, c);
* @endcode
*
* is equivalent in principle to:
* @code
* size_t some_result = a - b - c;
* @endcode
*
* except that it is possible for interested callers to handle overflow.
*
* @param result
* A pointer to the size_t variable that should receive the result of
* subtracting the given values from each other.
*
* @param ...
* The size_t values that should be subtracted from each other.
*
* @returns
* Zero if the subtraction was successful and did not overflow the limits
* of a size_t (did not go below zero), non-zero otherwise.
*/
#define guac_mem_ckd_sub(result, ...) \
PRIV_guac_mem_ckd_sub( \
result, \
sizeof((const size_t[]) { __VA_ARGS__ }) / sizeof(const size_t), \
(const size_t[]) { __VA_ARGS__ } \
)
/**
* Multiplies together each of the given values, returning the result directly.
* If the result of the multiplication overflows the limits of a size_t,
* execution of the current process is aborted entirely, and this function does
* not return.
*
* For example, the following:
* @code
* size_t some_result = guac_mem_ckd_mul_or_die(a, b, c);
* @endcode
*
* is equivalent in principle to:
* @code
* size_t some_result = a * b * c;
* @endcode
*
* except that an overflow condition will result in the process immediately
* terminating.
*
* @param ...
* The size_t values that should be multiplied together.
*
* @returns
* The result of the multiplication. If the multiplication operation would
* overflow the limits of a size_t, execution of the current process is
* aborted, and this function does not return.
*/
#define guac_mem_ckd_mul_or_die(...) \
PRIV_guac_mem_ckd_mul_or_die( \
sizeof((const size_t[]) { __VA_ARGS__ }) / sizeof(const size_t), \
(const size_t[]) { __VA_ARGS__ } \
)
/**
* Adds together each of the given values, returning the result directly. If
* the result of the addition overflows the limits of a size_t, execution of
* the current process is aborted entirely, and this function does not return.
*
* For example, the following:
* @code
* size_t some_result = guac_mem_ckd_add_or_die(a, b, c);
* @endcode
*
* is equivalent in principle to:
* @code
* size_t some_result = a + b + c;
* @endcode
*
* except that an overflow condition will result in the process immediately
* terminating.
*
* @param ...
* The size_t values that should be added together.
*
* @returns
* The result of the addition. If the addition operation would overflow the
* limits of a size_t, execution of the current process is aborted, and
* this function does not return.
*/
#define guac_mem_ckd_add_or_die(...) \
PRIV_guac_mem_ckd_add_or_die( \
sizeof((const size_t[]) { __VA_ARGS__ }) / sizeof(const size_t), \
(const size_t[]) { __VA_ARGS__ } \
)
/**
* Subtracts each of the given values from each other, returning the result
* directly. If the result of the subtraction overflows the limits of a size_t
* (goes below zero), execution of the current process is aborted entirely, and
* this function does not return.
*
* For example, the following:
* @code
* size_t some_result = guac_mem_ckd_sub_or_die(a, b, c);
* @endcode
*
* is equivalent in principle to:
* @code
* size_t some_result = a - b - c;
* @endcode
*
* except that an overflow condition will result in the process immediately
* terminating.
*
* @param ...
* The size_t values that should be subtracted from each other.
*
* @returns
* The result of the subtraction. If the subtraction operation would
* overflow the limits of a size_t (go below zero), execution of the
* current process is aborted, and this function does not return.
*/
#define guac_mem_ckd_sub_or_die(...) \
PRIV_guac_mem_ckd_sub_or_die( \
sizeof((const size_t[]) { __VA_ARGS__ }) / sizeof(const size_t), \
(const size_t[]) { __VA_ARGS__ } \
)
/**
* Reallocates a contiguous block of memory that was previously allocated with
* guac_mem_alloc(), guac_mem_zalloc(), guac_mem_realloc(), or one of their
* *_or_die() variants, returning a pointer to the first byte of that
* reallocated block of memory. If multiple sizes are provided, these sizes are
* multiplied together to produce the final size of the new block. If memory of
* the specified size cannot be allocated, or if multiplying the sizes would
* result in integer overflow, guac_error is set appropriately, the original
* block of memory is left untouched, and NULL is returned.
*
* This macro is analogous to the standard realloc(), but accepts a list of
* size factors instead of a requiring exactly one integer size.
*
* The returned pointer may be the same as the original pointer, but this is
* not guaranteed. If the returned pointer is different, the original pointer
* is automatically freed.
*
* The pointer returned by guac_mem_realloc() SHOULD be freed with a subsequent
* call to guac_mem_free(), but MAY instead be freed with a subsequent call to
* free().
*
* @param ...
* A series of one or more size_t values that should be multiplied together
* to produce the desired block size. At least one value MUST be provided.
*
* @returns
* A pointer to the first byte of the reallocated block of memory, or NULL
* if such a block could not be allocated. If a block of memory could not
* be allocated, guac_error is set appropriately and the original block of
* memory is left untouched.
*/
#define guac_mem_realloc(mem, ...) \
PRIV_guac_mem_realloc( \
mem, \
sizeof((const size_t[]) { __VA_ARGS__ }) / sizeof(const size_t), \
(const size_t[]) { __VA_ARGS__ } \
)
/**
* Reallocates a contiguous block of memory that was previously allocated with
* guac_mem_alloc(), guac_mem_zalloc(), guac_mem_realloc(), or one of their
* *_or_die() variants, returning a pointer to the first byte of that
* reallocated block of memory. If multiple sizes are provided, these sizes are
* multiplied together to produce the final size of the new block. If memory of
* the specified size cannot be allocated, execution of the current process is
* aborted entirely, and this function does not return.
*
* This macro is analogous to the standard realloc(), but accepts a list of
* size factors instead of a requiring exactly one integer size and does not
* return in the event a block cannot be allocated.
*
* The returned pointer may be the same as the original pointer, but this is
* not guaranteed. If the returned pointer is different, the original pointer
* is automatically freed.
*
* The pointer returned by guac_mem_realloc() SHOULD be freed with a subsequent
* call to guac_mem_free(), but MAY instead be freed with a subsequent call to
* free().
*
* @param ...
* A series of one or more size_t values that should be multiplied together
* to produce the desired block size. At least one value MUST be provided.
*
* @returns
* A pointer to the first byte of the reallocated block of memory. If a
* block of memory could not be allocated, execution of the current process
* is aborted, and this function does not return.
*/
#define guac_mem_realloc_or_die(mem, ...) \
PRIV_guac_mem_realloc_or_die( \
mem, \
sizeof((const size_t[]) { __VA_ARGS__ }) / sizeof(const size_t), \
(const size_t[]) { __VA_ARGS__ } \
)
/**
* Frees the memory block at the given pointer, which MUST have been allocated
* with guac_mem_alloc(), guac_mem_zalloc(), guac_mem_realloc(), or one of
* their *_or_die() variants. The pointer is automatically assigned a value of
* NULL after memory is freed. If the provided pointer is already NULL, this
* macro has no effect.
*
* @param mem
* A pointer to the memory to be freed.
*/
#define guac_mem_free(mem) (PRIV_guac_mem_free(mem), (mem) = NULL, (void) 0)
/**
* Frees the memory block at the given const pointer, which MUST have been
* allocated with guac_mem_alloc(), guac_mem_zalloc(), guac_mem_realloc(), or
* one of their *_or_die() variants. As the pointer is presumed constant, it is
* not automatically assigned a value of NULL after memory is freed. If the
* provided pointer is NULL, this macro has no effect.
*
* The guac_mem_free() macro should be used in favor of this macro. This macro
* should only be used in cases where a constant pointer is absolutely
* necessary.
*
* @param mem
* A pointer to the memory to be freed.
*/
#define guac_mem_free_const(mem) PRIV_guac_mem_free((void*) (mem))
#endif

View File

@ -0,0 +1,317 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef GUAC_PRIVATE_MEM_H
#define GUAC_PRIVATE_MEM_H
/**
* Provides functions used internally for allocating memory.
*
* WARNING: SYMBOLS DEFINED HERE ARE NOT INTENDED TO BE USED DIRECTLY BY
* ANYTHING OUTSIDE LIBGUAC! This header is used internally to define private
* symbols that are only intended for indirect public use through some other,
* non-private mechanism, such as a macro defined in the public API.
*
* @file mem.h
*/
#include <stddef.h>
/**
* Allocates a contiguous block of memory with the specified size, returning a
* pointer to the first byte of that block of memory. If multiple sizes are
* provided, these sizes are multiplied together to produce the final size of
* the new block. If memory of the specified size cannot be allocated, or if
* multiplying the sizes would result in integer overflow, guac_error is set
* appropriately and NULL is returned.
*
* This function is analogous to the standard malloc(), but accepts a list of
* size factors instead of a single integer size.
*
* The pointer returned by PRIV_guac_mem_alloc() SHOULD be freed with a
* subsequent call to guac_mem_free() or PRIV_guac_mem_free(), but MAY instead
* be freed with a subsequent call to free().
*
* @param factor_count
* The number of factors to multiply together to produce the desired block
* size.
*
* @param factors
* An array of one or more size_t values that should be multiplied together
* to produce the desired block size. At least one value MUST be provided.
*
* @returns
* A pointer to the first byte of the allocated block of memory, or NULL if
* such a block could not be allocated. If a block of memory could not be
* allocated, guac_error is set appropriately.
*/
void* PRIV_guac_mem_alloc(size_t factor_count, const size_t* factors);
/**
* Allocates a contiguous block of memory with the specified size and with all
* bytes initialized to zero, returning a pointer to the first byte of that
* block of memory. If multiple sizes are provided, these sizes are multiplied
* together to produce the final size of the new block. If memory of the
* specified size cannot be allocated, or if multiplying the sizes would result
* in integer overflow, guac_error is set appropriately and NULL is returned.
*
* This function is analogous to the standard calloc(), but accepts a list of
* size factors instead of a requiring exactly two integer sizes.
*
* The pointer returned by PRIV_guac_mem_zalloc() SHOULD be freed with a
* subsequent call to guac_mem_free() or PRIV_guac_mem_free(), but MAY instead
* be freed with a subsequent call to free().
*
* @param factor_count
* The number of factors to multiply together to produce the desired block
* size.
*
* @param factors
* An array of one or more size_t values that should be multiplied together
* to produce the desired block size. At least one value MUST be provided.
*
* @returns
* A pointer to the first byte of the allocated block of memory, or NULL if
* such a block could not be allocated. If a block of memory could not be
* allocated, guac_error is set appropriately.
*/
void* PRIV_guac_mem_zalloc(size_t factor_count, const size_t* factors);
/**
* Multiplies together each of the given values, storing the result in a size_t
* variable via the provided pointer. If the result of the multiplication
* overflows the limits of a size_t, non-zero is returned to signal failure.
*
* If the multiplication operation fails, the nature of any result stored in
* the provided pointer is undefined, as is whether a result is stored at all.
*
* @param result
* A pointer to the size_t variable that should receive the result of
* multiplying the given values.
*
* @param factor_count
* The number of factors to multiply together.
*
* @param factors
* An array of one or more size_t values that should be multiplied
* together. At least one value MUST be provided.
*
* @returns
* Zero if the multiplication was successful and did not overflow the
* limits of a size_t, non-zero otherwise.
*/
int PRIV_guac_mem_ckd_mul(size_t* result, size_t factor_count, const size_t* factors);
/**
* Adds together each of the given values, storing the result in a size_t
* variable via the provided pointer. If the result of the addition overflows
* the limits of a size_t, non-zero is returned to signal failure.
*
* If the addition operation fails, the nature of any result stored in the
* provided pointer is undefined, as is whether a result is stored at all.
*
* @param result
* A pointer to the size_t variable that should receive the result of
* adding the given values.
*
* @param term_count
* The number of terms to be added together.
*
* @param terms
* An array of one or more size_t values that should be added together. At
* least one value MUST be provided.
*
* @returns
* Zero if the addition was successful and did not overflow the limits of a
* size_t, non-zero otherwise.
*/
int PRIV_guac_mem_ckd_add(size_t* result, size_t term_count, const size_t* terms);
/**
* Subtracts each of the given values from each other, storing the result in a
* size_t variable via the provided pointer. If the result of the subtraction
* overflows the limits of a size_t (goes below zero), non-zero is returned to
* signal failure.
*
* If the subtraction operation fails, the nature of any result stored in the
* provided pointer is undefined, as is whether a result is stored at all.
*
* @param result
* A pointer to the size_t variable that should receive the result of
* subtracting the given values from each other.
*
* @param term_count
* The number of terms to be subtracted from each other.
*
* @param terms
* An array of one or more size_t values that should be subtracted from
* each other. At least one value MUST be provided.
*
* @returns
* Zero if the subtraction was successful and did not overflow the limits
* of a size_t (did not go below zero), non-zero otherwise.
*/
int PRIV_guac_mem_ckd_sub(size_t* result, size_t term_count, const size_t* terms);
/**
* Multiplies together each of the given values, returning the result directly.
* If the result of the multiplication overflows the limits of a size_t,
* execution of the current process is aborted entirely, and this function does
* not return.
*
* @param factor_count
* The number of factors to multiply together.
*
* @param factors
* An array of one or more size_t values that should be multiplied
* together. At least one value MUST be provided.
*
* @returns
* The result of the multiplication. If the multiplication operation would
* overflow the limits of a size_t, execution of the current process is
* aborted, and this function does not return.
*/
size_t PRIV_guac_mem_ckd_mul_or_die(size_t factor_count, const size_t* factors);
/**
* Adds together each of the given values, returning the result directly. If
* the result of the addition overflows the limits of a size_t, execution of
* the current process is aborted entirely, and this function does not return.
*
* @param term_count
* The number of terms to be added together.
*
* @param terms
* An array of one or more size_t values that should be added together. At
* least one value MUST be provided.
*
* @returns
* The result of the addition. If the addition operation would overflow the
* limits of a size_t, execution of the current process is aborted, and
* this function does not return.
*/
size_t PRIV_guac_mem_ckd_add_or_die(size_t term_count, const size_t* terms);
/**
* Subtracts each of the given values from each other, returning the result
* directly. If the result of the subtraction overflows the limits of a size_t
* (goes below zero), execution of the current process is aborted entirely, and
* this function does not return.
*
* @param term_count
* The number of terms to be subtracted from each other.
*
* @param terms
* An array of one or more size_t values that should be subtracted from
* each other. At least one value MUST be provided.
*
* @returns
* The result of the subtraction. If the subtraction operation would
* overflow the limits of a size_t (go below zero), execution of the
* current process is aborted, and this function does not return.
*/
size_t PRIV_guac_mem_ckd_sub_or_die(size_t term_count, const size_t* terms);
/**
* Reallocates a contiguous block of memory that was previously allocated with
* guac_mem_alloc(), guac_mem_zalloc(), guac_mem_realloc(), or one of their
* PRIV_guac_*() or *_or_die() variants, returning a pointer to the first byte
* of that reallocated block of memory. If multiple sizes are provided, these
* sizes are multiplied together to produce the final size of the new block. If
* memory of the specified size cannot be allocated, or if multiplying the
* sizes would result in integer overflow, guac_error is set appropriately, the
* original block of memory is left untouched, and NULL is returned.
*
* This function is analogous to the standard realloc(), but accepts a list of
* size factors instead of a requiring exactly one integer size.
*
* The returned pointer may be the same as the original pointer, but this is
* not guaranteed. If the returned pointer is different, the original pointer
* is automatically freed.
*
* The pointer returned by guac_mem_realloc() SHOULD be freed with a subsequent
* call to guac_mem_free() or PRIV_guac_mem_free(), but MAY instead be freed
* with a subsequent call to free().
*
* @param factor_count
* The number of factors to multiply together to produce the desired block
* size.
*
* @param factors
* An array of one or more size_t values that should be multiplied together
* to produce the desired block size. At least one value MUST be provided.
*
* @returns
* A pointer to the first byte of the reallocated block of memory, or NULL
* if such a block could not be allocated. If a block of memory could not
* be allocated, guac_error is set appropriately and the original block of
* memory is left untouched.
*/
void* PRIV_guac_mem_realloc(void* mem, size_t factor_count, const size_t* factors);
/**
* Reallocates a contiguous block of memory that was previously allocated with
* guac_mem_alloc(), guac_mem_zalloc(), guac_mem_realloc(), or one of their
* PRIV_guac_*() or *_or_die() variants, returning a pointer to the first byte
* of that reallocated block of memory. If multiple sizes are provided, these
* sizes are multiplied together to produce the final size of the new block. If
* memory of the specified size cannot be allocated, or if multiplying the
* sizes would result in integer overflow, execution of the current process is
* aborted entirely, and this function does not return.
*
* This function is analogous to the standard realloc(), but accepts a list of
* size factors instead of a requiring exactly one integer size and does not
* return in the event a block cannot be allocated.
*
* The returned pointer may be the same as the original pointer, but this is
* not guaranteed. If the returned pointer is different, the original pointer
* is automatically freed.
*
* The pointer returned by guac_mem_realloc() SHOULD be freed with a subsequent
* call to guac_mem_free() or PRIV_guac_mem_free(), but MAY instead be freed
* with a subsequent call to free().
*
* @param factor_count
* The number of factors to multiply together to produce the desired block
* size.
*
* @param factors
* An array of one or more size_t values that should be multiplied together
* to produce the desired block size. At least one value MUST be provided.
*
* @returns
* A pointer to the first byte of the reallocated block of memory. If a
* block of memory could not be allocated, execution of the current process
* is aborted, and this function does not return.
*/
void* PRIV_guac_mem_realloc_or_die(void* mem, size_t factor_count, const size_t* factors);
/**
* Frees the memory block at the given pointer, which MUST have been allocated
* with guac_mem_alloc(), guac_mem_zalloc(), guac_mem_realloc(), or one of
* their PRIV_guac_*() or *_or_die() variants. If the provided pointer is NULL,
* this function has no effect.
*
* @param mem
* A pointer to the memory to be freed.
*/
void PRIV_guac_mem_free(void* mem);
#endif

View File

@ -132,8 +132,17 @@ size_t guac_strlcat(char* restrict dest, const char* restrict src, size_t n);
char* guac_strnstr(const char *haystack, const char *needle, size_t len);
/**
* Simple wrapper for strdup() which behaves identically to standard strdup(),
* except that NULL will be returned if the provided string is NULL.
* Duplicates the given string, returning a newly-allocated string containing
* the same contents. The provided string must be null-terminated. The size of
* the memory block for the newly-allocated string is only guaranteed to
* include enough space for the contents of the provided string, including null
* terminator.
*
* The pointer returned by guac_strdup() SHOULD be freed with a subsequent call
* to guac_mem_free(), but MAY instead be freed with a subsequent call to free().
*
* This function behaves identically to standard strdup(), except that NULL
* will be returned if the provided string is NULL.
*
* @param str
* The string to duplicate as a newly-allocated string.

View File

@ -19,6 +19,7 @@
#include "config.h"
#include "guacamole/mem.h"
#include "guacamole/error.h"
#include "id.h"
@ -68,7 +69,7 @@ char* guac_generate_id(char prefix) {
#endif
/* Allocate buffer for future formatted ID */
buffer = malloc(GUAC_UUID_LEN + 2);
buffer = guac_mem_alloc(GUAC_UUID_LEN + 2);
if (buffer == NULL) {
#ifndef HAVE_LIBUUID
uuid_destroy(uuid);
@ -86,7 +87,7 @@ char* guac_generate_id(char prefix) {
#else
size_t identifier_length = GUAC_UUID_LEN + 1;
if (uuid_export(uuid, UUID_FMT_STR, &identifier, &identifier_length) != UUID_RC_OK) {
free(buffer);
guac_mem_free(buffer);
uuid_destroy(uuid);
guac_error = GUAC_STATUS_INTERNAL_ERROR;
guac_error_message = "Conversion of UUID to unique ID failed";

View File

@ -23,13 +23,16 @@
/**
* Generates a guaranteed-unique identifier which is a total of 37 characters
* long, having the given single-character prefix. The resulting identifier
* must be freed with a call to free() when no longer needed. If an error
* must be freed with a call to guac_mem_free() when no longer needed. If an error
* occurs, NULL is returned, no memory is allocated, and guac_error is set
* appropriately.
*
* @param prefix The single-character prefix to use.
* @return A newly-allocated unique identifier with the given prefix, or
* NULL if the identifier could not be generated.
* @param prefix
* The single-character prefix to use.
*
* @return
* A newly-allocated unique identifier with the given prefix, or NULL if
* the identifier could not be generated.
*/
char* guac_generate_id(char prefix);

251
src/libguac/mem.c Normal file
View File

@ -0,0 +1,251 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include "guacamole/error.h"
#include "guacamole/mem.h"
#include "guacamole/private/mem.h"
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
/*
* ============================================================================
*
* IMPORTANT: For compatibility with past usages of libguac, all allocation
* functions implemented here need to remain compatible with the standard
* free() function, as there are past usages of libguac functions that expect
* allocated memory to have been allocated with malloc() or similar. Some good
* examples of this would be guac_strdup() or guac_user_parse_args_string().
*
* It is OK if these allocation functions add new functionality beyond what
* malloc() provides, but care must be taken to ensure free() can still be used
* safely and without leaks, even if guac_mem_free() will always be preferred.
*
* It is further OK for guac_mem_free() to be incompatible with free() and only
* usable on memory blocks allocated through guac_mem_alloc() and similar.
*
* ============================================================================
*/
int PRIV_guac_mem_ckd_mul(size_t* result, size_t factor_count, const size_t* factors) {
/* Consider calculation invalid if no factors are provided at all */
if (factor_count == 0)
return 1;
/* Multiply all provided factors together */
ssize_t size = *(factors++);
while (--factor_count && size) {
size_t factor = *(factors++);
/* Fail if including this additional factor would exceed SIZE_MAX */
size_t max_factor = SIZE_MAX / size;
if (factor > max_factor)
return 1;
size *= factor;
}
*result = size;
return 0;
}
int PRIV_guac_mem_ckd_add(size_t* result, size_t term_count, const size_t* terms) {
/* Consider calculation invalid if no terms are provided at all */
if (term_count == 0)
return 1;
/* Multiply all provided terms together */
ssize_t size = *(terms++);
while (--term_count) {
size_t term = *(terms++);
/* Fail if including this additional term would exceed SIZE_MAX */
size_t max_term = SIZE_MAX - size;
if (term > max_term)
return 1;
size += term;
}
*result = size;
return 0;
}
int PRIV_guac_mem_ckd_sub(size_t* result, size_t term_count, const size_t* terms) {
/* Consider calculation invalid if no terms are provided at all */
if (term_count == 0)
return 1;
/* Multiply all provided terms together */
ssize_t size = *(terms++);
while (--term_count) {
size_t term = *(terms++);
/* Fail if including this additional term would wrap past zero */
if (term > size)
return 1;
size -= term;
}
*result = size;
return 0;
}
size_t PRIV_guac_mem_ckd_mul_or_die(size_t factor_count, const size_t* factors) {
/* Perform request multiplication, aborting the entire process if the
* calculation overflows */
size_t result = 0;
if (PRIV_guac_mem_ckd_mul(&result, factor_count, factors))
abort();
return result;
}
size_t PRIV_guac_mem_ckd_add_or_die(size_t term_count, const size_t* terms) {
/* Perform request addition, aborting the entire process if the calculation
* overflows */
size_t result = 0;
if (PRIV_guac_mem_ckd_add(&result, term_count, terms))
abort();
return result;
}
size_t PRIV_guac_mem_ckd_sub_or_die(size_t term_count, const size_t* terms) {
/* Perform request subtraction, aborting the entire process if the
* calculation overflows */
size_t result = 0;
if (PRIV_guac_mem_ckd_sub(&result, term_count, terms))
abort();
return result;
}
void* PRIV_guac_mem_alloc(size_t factor_count, const size_t* factors) {
size_t size = 0;
if (PRIV_guac_mem_ckd_mul(&size, factor_count, factors)) {
guac_error = GUAC_STATUS_NO_MEMORY;
return NULL;
}
else if (size == 0)
return NULL;
void* mem = malloc(size);
if (mem == NULL) {
/* C does not require that malloc() set errno (though POSIX does). For
* portability, we set guac_error here regardless of the underlying
* behavior of malloc(). */
guac_error = GUAC_STATUS_NO_MEMORY;
}
return mem;
}
void* PRIV_guac_mem_zalloc(size_t factor_count, const size_t* factors) {
size_t size = 0;
if (PRIV_guac_mem_ckd_mul(&size, factor_count, factors)) {
guac_error = GUAC_STATUS_NO_MEMORY;
return NULL;
}
else if (size == 0)
return NULL;
void* mem = calloc(1, size);
if (mem == NULL) {
/* C does not require that calloc() set errno (though POSIX does). For
* portability, we set guac_error here regardless of the underlying
* behavior of calloc(). */
guac_error = GUAC_STATUS_NO_MEMORY;
}
return mem;
}
void* PRIV_guac_mem_realloc(void* mem, size_t factor_count, const size_t* factors) {
size_t size = 0;
if (PRIV_guac_mem_ckd_mul(&size, factor_count, factors)) {
guac_error = GUAC_STATUS_NO_MEMORY;
return NULL;
}
/* Resize to 0 is equivalent to free() */
if (size == 0) {
guac_mem_free(mem);
return NULL;
}
void* resized_mem = realloc(mem, size);
if (resized_mem == NULL) {
/* C does not require that realloc() set errno (though POSIX does). For
* portability, we set guac_error here regardless of the underlying
* behavior of realloc(). */
guac_error = GUAC_STATUS_NO_MEMORY;
}
return resized_mem;
}
void* PRIV_guac_mem_realloc_or_die(void* mem, size_t factor_count, const size_t* factors) {
/* Reset any past errors for upcoming error check */
guac_error = GUAC_STATUS_SUCCESS;
/* Perform requested resize, aborting the entire process if this cannot be
* done */
void* resized_mem = PRIV_guac_mem_realloc(mem, factor_count, factors);
if (resized_mem == NULL && guac_error != GUAC_STATUS_SUCCESS)
abort();
return resized_mem;
}
void PRIV_guac_mem_free(void* mem) {
free(mem);
}

View File

@ -19,6 +19,7 @@
#include "config.h"
#include "guacamole/mem.h"
#include "palette.h"
#include <cairo/cairo.h>
@ -38,8 +39,7 @@ guac_palette* guac_palette_alloc(cairo_surface_t* surface) {
unsigned char* data = cairo_image_surface_get_data(surface);
/* Allocate palette */
guac_palette* palette = (guac_palette*) malloc(sizeof(guac_palette));
memset(palette, 0, sizeof(guac_palette));
guac_palette* palette = (guac_palette*) guac_mem_zalloc(sizeof(guac_palette));
for (y=0; y<height; y++) {
for (x=0; x<width; x++) {
@ -129,6 +129,6 @@ int guac_palette_find(guac_palette* palette, int color) {
}
void guac_palette_free(guac_palette* palette) {
free(palette);
guac_mem_free(palette);
}

View File

@ -19,6 +19,7 @@
#include "config.h"
#include "guacamole/mem.h"
#include "guacamole/error.h"
#include "guacamole/parser.h"
#include "guacamole/socket.h"
@ -39,7 +40,7 @@ static void guac_parser_reset(guac_parser* parser) {
guac_parser* guac_parser_alloc() {
/* Allocate space for parser */
guac_parser* parser = malloc(sizeof(guac_parser));
guac_parser* parser = guac_mem_alloc(sizeof(guac_parser));
if (parser == NULL) {
guac_error = GUAC_STATUS_NO_MEMORY;
guac_error_message = "Insufficient memory to allocate parser";
@ -313,6 +314,6 @@ int guac_parser_shift(guac_parser* parser, void* buffer, int length) {
}
void guac_parser_free(guac_parser* parser) {
free(parser);
guac_mem_free(parser);
}

View File

@ -19,6 +19,7 @@
#include "config.h"
#include "guacamole/mem.h"
#include "guacamole/pool.h"
#include <stdlib.h>
@ -26,7 +27,7 @@
guac_pool* guac_pool_alloc(int size) {
pthread_mutexattr_t lock_attributes;
guac_pool* pool = malloc(sizeof(guac_pool));
guac_pool* pool = guac_mem_alloc(sizeof(guac_pool));
/* If unable to allocate, just return NULL. */
if (pool == NULL)
@ -57,14 +58,14 @@ void guac_pool_free(guac_pool* pool) {
guac_pool_int* old = current;
current = current->__next;
free(old);
guac_mem_free(old);
}
/* Destroy lock */
pthread_mutex_destroy(&(pool->__lock));
/* Free pool */
free(pool);
guac_mem_free(pool);
}
@ -89,7 +90,7 @@ int guac_pool_next_int(guac_pool* pool) {
/* If only one element exists, reset pool to empty. */
if (pool->__tail == pool->__head) {
free(pool->__head);
guac_mem_free(pool->__head);
pool->__head = NULL;
pool->__tail = NULL;
}
@ -98,7 +99,7 @@ int guac_pool_next_int(guac_pool* pool) {
else {
guac_pool_int* old_head = pool->__head;
pool->__head = old_head->__next;
free(old_head);
guac_mem_free(old_head);
}
/* Return retrieved value. */
@ -109,7 +110,7 @@ int guac_pool_next_int(guac_pool* pool) {
void guac_pool_free_int(guac_pool* pool, int value) {
/* Allocate and initialize new returned value */
guac_pool_int* pool_int = malloc(sizeof(guac_pool_int));
guac_pool_int* pool_int = guac_mem_alloc(sizeof(guac_pool_int));
pool_int->value = value;
pool_int->__next = NULL;

View File

@ -19,6 +19,7 @@
#include "config.h"
#include "guacamole/mem.h"
#include "guacamole/audio.h"
#include "guacamole/client.h"
#include "guacamole/protocol.h"
@ -52,13 +53,12 @@ static void raw_encoder_begin_handler(guac_audio_stream* audio) {
raw_encoder_send_audio(audio, audio->client->socket);
/* Allocate and init encoder state */
audio->data = state = malloc(sizeof(raw_encoder_state));
audio->data = state = guac_mem_alloc(sizeof(raw_encoder_state));
state->written = 0;
state->length = GUAC_RAW_ENCODER_BUFFER_SIZE
* audio->rate * audio->channels * audio->bps
/ 8 / 1000;
state->length = guac_mem_ckd_mul_or_die(GUAC_RAW_ENCODER_BUFFER_SIZE,
audio->rate, audio->channels, audio->bps) / 8 / 1000;
state->buffer = malloc(state->length);
state->buffer = guac_mem_alloc(state->length);
}
@ -78,8 +78,8 @@ static void raw_encoder_end_handler(guac_audio_stream* audio) {
guac_protocol_send_end(audio->client->socket, audio->stream);
/* Free state information */
free(state->buffer);
free(state);
guac_mem_free(state->buffer);
guac_mem_free(state);
}

View File

@ -52,7 +52,7 @@ typedef struct raw_encoder_state {
/**
* Size of the PCM buffer, in bytes.
*/
int length;
size_t length;
/**
* The current number of bytes stored within the PCM buffer.

View File

@ -17,6 +17,7 @@
* under the License.
*/
#include "guacamole/mem.h"
#include "guacamole/client.h"
#include "guacamole/protocol.h"
#include "guacamole/recording.h"
@ -162,7 +163,7 @@ guac_recording* guac_recording_create(guac_client* client,
}
/* Create recording structure with reference to underlying socket */
guac_recording* recording = malloc(sizeof(guac_recording));
guac_recording* recording = guac_mem_alloc(sizeof(guac_recording));
recording->socket = guac_socket_open(fd);
recording->include_output = include_output;
recording->include_mouse = include_mouse;
@ -191,7 +192,7 @@ void guac_recording_free(guac_recording* recording) {
guac_socket_free(recording->socket);
/* Free recording itself */
free(recording);
guac_mem_free(recording);
}

View File

@ -19,6 +19,7 @@
#include "config.h"
#include "guacamole/mem.h"
#include "guacamole/client.h"
#include "guacamole/error.h"
#include "guacamole/socket.h"
@ -360,7 +361,7 @@ static int __guac_socket_broadcast_free_handler(guac_socket* socket) {
/* Destroy locks */
pthread_mutex_destroy(&(data->socket_lock));
free(data);
guac_mem_free(data);
return 0;
}
@ -387,7 +388,7 @@ static guac_socket* __guac_socket_init(
/* Allocate socket and associated data */
guac_socket* socket = guac_socket_alloc();
guac_socket_broadcast_data* data =
malloc(sizeof(guac_socket_broadcast_data));
guac_mem_alloc(sizeof(guac_socket_broadcast_data));
/* Set the provided broadcast handler */
data->broadcast_handler = broadcast_handler;

View File

@ -19,6 +19,7 @@
#include "config.h"
#include "guacamole/mem.h"
#include "guacamole/error.h"
#include "guacamole/socket.h"
#include "wait-fd.h"
@ -382,7 +383,7 @@ static int guac_socket_fd_free_handler(guac_socket* socket) {
/* Close file descriptor */
close(data->fd);
free(data);
guac_mem_free(data);
return 0;
}
@ -423,7 +424,7 @@ guac_socket* guac_socket_open(int fd) {
/* Allocate socket and associated data */
guac_socket* socket = guac_socket_alloc();
guac_socket_fd_data* data = malloc(sizeof(guac_socket_fd_data));
guac_socket_fd_data* data = guac_mem_alloc(sizeof(guac_socket_fd_data));
/* Store file descriptor as socket data */
data->fd = fd;

View File

@ -19,6 +19,7 @@
#include "config.h"
#include "guacamole/mem.h"
#include "guacamole/protocol.h"
#include "guacamole/socket.h"
#include "guacamole/unicode.h"
@ -274,7 +275,7 @@ static int guac_socket_nest_free_handler(guac_socket* socket) {
/* Free associated data */
guac_socket_nest_data* data = (guac_socket_nest_data*) socket->data;
free(data);
guac_mem_free(data);
return 0;
@ -314,7 +315,7 @@ guac_socket* guac_socket_nest(guac_socket* parent, int index) {
/* Allocate socket and associated data */
guac_socket* socket = guac_socket_alloc();
guac_socket_nest_data* data = malloc(sizeof(guac_socket_nest_data));
guac_socket_nest_data* data = guac_mem_alloc(sizeof(guac_socket_nest_data));
/* Store nested socket details as socket data */
data->parent = parent;

View File

@ -19,6 +19,7 @@
#include "config.h"
#include "guacamole/mem.h"
#include "guacamole/error.h"
#include "guacamole/socket-ssl.h"
#include "guacamole/socket.h"
@ -96,7 +97,7 @@ static int __guac_socket_ssl_free_handler(guac_socket* socket) {
/* Close file descriptor */
close(data->fd);
free(data);
guac_mem_free(data);
return 0;
}
@ -109,7 +110,7 @@ guac_socket* guac_socket_open_secure(SSL_CTX* context, int fd) {
/* Allocate socket and associated data */
guac_socket* socket = guac_socket_alloc();
guac_socket_ssl_data* data = malloc(sizeof(guac_socket_ssl_data));
guac_socket_ssl_data* data = guac_mem_alloc(sizeof(guac_socket_ssl_data));
/* Init SSL */
data->context = context;
@ -122,7 +123,7 @@ guac_socket* guac_socket_open_secure(SSL_CTX* context, int fd) {
guac_error = GUAC_STATUS_INTERNAL_ERROR;
guac_error_message = "SSL accept failed";
free(data);
guac_mem_free(data);
guac_socket_free(socket);
SSL_free(ssl);
return NULL;

View File

@ -19,6 +19,7 @@
#include "config.h"
#include "guacamole/mem.h"
#include "guacamole/socket.h"
#include <stdlib.h>
@ -202,7 +203,7 @@ static int __guac_socket_tee_free_handler(guac_socket* socket) {
guac_socket_free(data->secondary);
/* Freeing the tee socket always succeeds */
free(data);
guac_mem_free(data);
return 0;
}
@ -210,7 +211,7 @@ static int __guac_socket_tee_free_handler(guac_socket* socket) {
guac_socket* guac_socket_tee(guac_socket* primary, guac_socket* secondary) {
/* Set up socket to split outout into a file */
guac_socket_tee_data* data = malloc(sizeof(guac_socket_tee_data));
guac_socket_tee_data* data = guac_mem_alloc(sizeof(guac_socket_tee_data));
data->primary = primary;
data->secondary = secondary;

View File

@ -17,6 +17,7 @@
* under the License.
*/
#include "guacamole/mem.h"
#include "guacamole/error.h"
#include "guacamole/socket.h"
@ -378,7 +379,7 @@ static int guac_socket_wsa_free_handler(guac_socket* socket) {
/* Close socket */
closesocket(data->sock);
free(data);
guac_mem_free(data);
return 0;
}
@ -419,7 +420,7 @@ guac_socket* guac_socket_open_wsa(SOCKET sock) {
/* Allocate socket and associated data */
guac_socket* socket = guac_socket_alloc();
guac_socket_wsa_data* data = malloc(sizeof(guac_socket_wsa_data));
guac_socket_wsa_data* data = guac_mem_alloc(sizeof(guac_socket_wsa_data));
/* Store socket as socket data */
data->sock = sock;

View File

@ -19,6 +19,7 @@
#include "config.h"
#include "guacamole/mem.h"
#include "guacamole/error.h"
#include "guacamole/protocol.h"
#include "guacamole/socket.h"
@ -141,7 +142,7 @@ int guac_socket_select(guac_socket* socket, int usec_timeout) {
guac_socket* guac_socket_alloc() {
guac_socket* socket = malloc(sizeof(guac_socket));
guac_socket* socket = guac_mem_alloc(sizeof(guac_socket));
/* If no memory available, return with error */
if (socket == NULL) {
@ -213,7 +214,7 @@ void guac_socket_free(guac_socket* socket) {
pthread_join(socket->__keep_alive_thread, NULL);
}
free(socket);
guac_mem_free(socket);
}
ssize_t guac_socket_write_int(guac_socket* socket, int64_t i) {

View File

@ -19,6 +19,8 @@
#include "config.h"
#include "guacamole/mem.h"
#include <stddef.h>
#include <string.h>
@ -119,8 +121,18 @@ char* guac_strdup(const char* str) {
if (str == NULL)
return NULL;
/* Otherwise just invoke strdup() */
return strdup(str);
/* Do not attempt to duplicate if the length is somehow magically so
* obscenely large that it will not be possible to add a null terminator */
size_t length;
if (guac_mem_ckd_add(&length, strlen(str), 1))
return NULL;
/* Otherwise just copy to a new string in same manner as strdup() */
void* new_str = guac_mem_alloc(length);
if (new_str != NULL)
memcpy(new_str, str, length);
return new_str;
}

View File

@ -33,10 +33,24 @@ ACLOCAL_AMFLAGS = -I m4
check_PROGRAMS = test_libguac
TESTS = $(check_PROGRAMS)
noinst_HEADERS = \
assert-signal.h
test_libguac_SOURCES = \
client/buffer_pool.c \
client/layer_pool.c \
id/generate.c \
mem/alloc.c \
mem/ckd_add.c \
mem/ckd_add_or_die.c \
mem/ckd_mul.c \
mem/ckd_mul_or_die.c \
mem/ckd_sub.c \
mem/ckd_sub_or_die.c \
mem/free.c \
mem/realloc.c \
mem/realloc_or_die.c \
mem/zalloc.c \
parser/append.c \
parser/read.c \
pool/next_free.c \

View File

@ -0,0 +1,67 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef GUAC_LIBGUAC_TESTS_ASSERT_SIGNAL_H
#define GUAC_LIBGUAC_TESTS_ASSERT_SIGNAL_H
#include <CUnit/CUnit.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
/**
* Verifies that the given test terminates the calling process with the given
* signal.
*
* @param sig
* The signal that is expected to terminate the calling process.
*
* @param test
* The test that is expected to terminate the calling process with the
* given signal.
*/
#define ASSERT_SIGNALLED(sig, test) \
do { \
\
/* Fork to ensure test can safely terminate */ \
pid_t _child = fork(); \
CU_ASSERT_NOT_EQUAL_FATAL(_child, -1); \
\
/* Run test strictly within child process */ \
if (_child == 0) { \
do { test; } while (0); \
exit(0); \
} \
\
/* Wait for child process to terminate */ \
int _status = 0; \
CU_ASSERT_EQUAL_FATAL(waitpid(_child, &_status, 0), _child); \
\
/* Verify process terminated with expected signal */ \
if (WIFSIGNALED(_status)) { \
CU_ASSERT_EQUAL(WTERMSIG(_status), (sig)); \
} \
else \
CU_FAIL("Process did not terminate due to a signal"); \
\
} while (0)
#endif

View File

@ -17,6 +17,7 @@
* under the License.
*/
#include "guacamole/mem.h"
#include "id.h"
#include <CUnit/CUnit.h>
@ -40,8 +41,8 @@ void test_id__unique() {
/* Both strings should be different */
CU_ASSERT_STRING_NOT_EQUAL(id1, id2);
free(id1);
free(id2);
guac_mem_free(id1);
guac_mem_free(id2);
}
@ -62,7 +63,7 @@ void test_id__format() {
CU_ASSERT_EQUAL(items_read, 6);
CU_ASSERT_EQUAL(strlen(id), 37);
free(id);
guac_mem_free(id);
}
@ -77,12 +78,12 @@ void test_id__prefix() {
id = guac_generate_id('a');
CU_ASSERT_PTR_NOT_NULL_FATAL(id);
CU_ASSERT_EQUAL(id[0], 'a');
free(id);
guac_mem_free(id);
id = guac_generate_id('b');
CU_ASSERT_PTR_NOT_NULL_FATAL(id);
CU_ASSERT_EQUAL(id[0], 'b');
free(id);
guac_mem_free(id);
}

View File

@ -0,0 +1,73 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <CUnit/CUnit.h>
#include <guacamole/mem.h>
#include <stdint.h>
/**
* Test which verifies that guac_mem_alloc() returns NULL for all inputs involving
* at least one zero value.
*/
void test_mem__alloc_fail_zero() {
CU_ASSERT_PTR_NULL(guac_mem_alloc(0));
CU_ASSERT_PTR_NULL(guac_mem_alloc(0, 0));
CU_ASSERT_PTR_NULL(guac_mem_alloc(0, 0, 0));
CU_ASSERT_PTR_NULL(guac_mem_alloc(0, 0, 0, 0));
CU_ASSERT_PTR_NULL(guac_mem_alloc(0, 0, 0, 0, 0));
CU_ASSERT_PTR_NULL(guac_mem_alloc(1, 0));
CU_ASSERT_PTR_NULL(guac_mem_alloc(3, 2, 0));
CU_ASSERT_PTR_NULL(guac_mem_alloc(5, 0, 8, 9));
CU_ASSERT_PTR_NULL(guac_mem_alloc(99, 99, 99, 0, 99));
}
/**
* Test which verifies that guac_mem_alloc() successfully allocates blocks of
* memory for inputs that can reasonably be expected to succeed.
*/
void test_mem__alloc_success() {
void* ptr;
ptr = guac_mem_alloc(123);
CU_ASSERT_PTR_NOT_NULL(ptr);
guac_mem_free(ptr);
ptr = guac_mem_alloc(123, 456);
CU_ASSERT_PTR_NOT_NULL(ptr);
guac_mem_free(ptr);
ptr = guac_mem_alloc(123, 456, 789);
CU_ASSERT_PTR_NOT_NULL(ptr);
guac_mem_free(ptr);
}
/**
* Test which verifies that guac_mem_alloc() fails to allocate blocks of memory
* that exceed the capacity of a size_t.
*/
void test_mem__alloc_fail_large() {
CU_ASSERT_PTR_NULL(guac_mem_alloc(123, 456, SIZE_MAX));
CU_ASSERT_PTR_NULL(guac_mem_alloc(SIZE_MAX / 2, SIZE_MAX / 2));
}

View File

@ -0,0 +1,103 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <CUnit/CUnit.h>
#include <guacamole/mem.h>
#include <stdint.h>
/**
* Test which verifies that guac_mem_ckd_add() calculates results correctly for
* all inputs involving at least one zero value.
*/
void test_mem__ckd_add_zero() {
size_t result = SIZE_MAX;
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_add(&result, 0));
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_add(&result, 0, 0));
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_add(&result, 0, 0, 0));
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_add(&result, 0, 0, 0, 0));
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_add(&result, 0, 0, 0, 0, 0));
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_add(&result, 0, 1));
CU_ASSERT_EQUAL(result, 1);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_add(&result, 1, 0));
CU_ASSERT_EQUAL(result, 1);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_add(&result, 3, 2, 0));
CU_ASSERT_EQUAL(result, 3 + 2);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_add(&result, 5, 0, 8, 9));
CU_ASSERT_EQUAL(result, 5 + 8 + 9);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_add(&result, 99, 99, 99, 0, 99));
CU_ASSERT_EQUAL(result, 99 + 99 + 99 + 99);
}
/**
* Test which verifies that guac_mem_ckd_add() successfully calculates expected
* values for relatively small integer inputs.
*/
void test_mem__ckd_add_small() {
size_t result = SIZE_MAX;
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_add(&result, 123));
CU_ASSERT_EQUAL(result, 123);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_add(&result, 123, 456));
CU_ASSERT_EQUAL(result, 123 + 456);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_add(&result, 123, 456, 789));
CU_ASSERT_EQUAL(result, 123 + 456 + 789);
}
/**
* Test which verifies that guac_mem_ckd_add() behaves as expected for
* relatively large integer inputs, including inputs that cause overflow beyond
* the capacity of a size_t.
*/
void test_mem__ckd_add_large() {
size_t result = 0;
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_add(&result, SIZE_MAX));
CU_ASSERT_EQUAL(result, SIZE_MAX);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_add(&result, SIZE_MAX / 2, SIZE_MAX / 2));
CU_ASSERT_EQUAL(result, (SIZE_MAX / 2) * 2);
CU_ASSERT_TRUE_FATAL(guac_mem_ckd_add(&result, SIZE_MAX, 1));
CU_ASSERT_TRUE_FATAL(guac_mem_ckd_add(&result, 123, 456, SIZE_MAX));
CU_ASSERT_TRUE_FATAL(guac_mem_ckd_add(&result, SIZE_MAX / 2, SIZE_MAX / 2, 2));
}

View File

@ -0,0 +1,72 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include "assert-signal.h"
#include <CUnit/CUnit.h>
#include <guacamole/mem.h>
#include <stdint.h>
/**
* Test which verifies that guac_mem_ckd_add_or_die() calculates results
* correctly for all inputs involving at least one zero value.
*/
void test_mem__ckd_add_or_die_zero() {
CU_ASSERT_EQUAL(guac_mem_ckd_add_or_die(0), 0);
CU_ASSERT_EQUAL(guac_mem_ckd_add_or_die(0, 0), 0);
CU_ASSERT_EQUAL(guac_mem_ckd_add_or_die(0, 0, 0), 0);
CU_ASSERT_EQUAL(guac_mem_ckd_add_or_die(0, 0, 0, 0), 0);
CU_ASSERT_EQUAL(guac_mem_ckd_add_or_die(0, 0, 0, 0, 0), 0);
CU_ASSERT_EQUAL(guac_mem_ckd_add_or_die(0, 1), 1);
CU_ASSERT_EQUAL(guac_mem_ckd_add_or_die(1, 0), 1);
CU_ASSERT_EQUAL(guac_mem_ckd_add_or_die(3, 2, 0), 3 + 2);
CU_ASSERT_EQUAL(guac_mem_ckd_add_or_die(5, 0, 8, 9), 5 + 8 + 9);
CU_ASSERT_EQUAL(guac_mem_ckd_add_or_die(99, 99, 99, 0, 99), 99 + 99 + 99 + 99);
}
/**
* Test which verifies that guac_mem_ckd_add_or_die() successfully calculates
* expected values for relatively small integer inputs.
*/
void test_mem__ckd_add_or_die_small() {
CU_ASSERT_EQUAL(guac_mem_ckd_add_or_die(123), 123);
CU_ASSERT_EQUAL(guac_mem_ckd_add_or_die(123, 456), 123 + 456);
CU_ASSERT_EQUAL(guac_mem_ckd_add_or_die(123, 456, 789), 123 + 456 + 789);
}
/**
* Test which verifies that guac_mem_ckd_add_or_die() behaves as expected for
* relatively large integer inputs, including inputs that cause overflow beyond
* the capacity of a size_t.
*/
void test_mem__ckd_add_or_die_large() {
CU_ASSERT_EQUAL(guac_mem_ckd_add_or_die(SIZE_MAX), SIZE_MAX);
CU_ASSERT_EQUAL(guac_mem_ckd_add_or_die(SIZE_MAX / 2, SIZE_MAX / 2), (SIZE_MAX / 2) * 2);
ASSERT_SIGNALLED(SIGABRT, guac_mem_ckd_add_or_die(SIZE_MAX, 1));
ASSERT_SIGNALLED(SIGABRT, guac_mem_ckd_add_or_die(123, 456, SIZE_MAX));
ASSERT_SIGNALLED(SIGABRT, guac_mem_ckd_add_or_die(SIZE_MAX / 2, SIZE_MAX / 2, 2));
}

View File

@ -0,0 +1,99 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <CUnit/CUnit.h>
#include <guacamole/mem.h>
#include <stdint.h>
/**
* Test which verifies that guac_mem_ckd_mul() calculates zero values for all
* inputs involving at least one zero value.
*/
void test_mem__ckd_mul_zero() {
size_t result = SIZE_MAX;
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_mul(&result, 0));
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_mul(&result, 0, 0));
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_mul(&result, 0, 0, 0));
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_mul(&result, 0, 0, 0, 0));
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_mul(&result, 0, 0, 0, 0, 0));
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_mul(&result, 0, 1));
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_mul(&result, 1, 0));
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_mul(&result, 3, 2, 0));
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_mul(&result, 5, 0, 8, 9));
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_mul(&result, 99, 99, 99, 0, 99));
CU_ASSERT_EQUAL(result, 0);
}
/**
* Test which verifies that guac_mem_ckd_mul() successfully calculates expected
* values for relatively small integer inputs.
*/
void test_mem__ckd_mul_small() {
size_t result = SIZE_MAX;
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_mul(&result, 123));
CU_ASSERT_EQUAL(result, 123);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_mul(&result, 123, 456));
CU_ASSERT_EQUAL(result, 123 * 456);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_mul(&result, 123, 456, 789));
CU_ASSERT_EQUAL(result, 123 * 456 * 789);
}
/**
* Test which verifies that guac_mem_ckd_mul() behaves as expected for
* relatively large integer inputs, including inputs that cause overflow beyond
* the capacity of a size_t.
*/
void test_mem__ckd_mul_large() {
size_t result = 0;
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_mul(&result, SIZE_MAX));
CU_ASSERT_EQUAL(result, SIZE_MAX);
CU_ASSERT_TRUE_FATAL(guac_mem_ckd_mul(&result, 123, 456, SIZE_MAX));
CU_ASSERT_TRUE_FATAL(guac_mem_ckd_mul(&result, SIZE_MAX / 2, SIZE_MAX / 2));
}

View File

@ -0,0 +1,68 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include "assert-signal.h"
#include <CUnit/CUnit.h>
#include <guacamole/mem.h>
#include <stdint.h>
/**
* Test which verifies that guac_mem_ckd_mul_or_die() calculates zero values
* for all inputs involving at least one zero value.
*/
void test_mem__ckd_mul_or_die_zero() {
CU_ASSERT_EQUAL(guac_mem_ckd_mul_or_die(0), 0);
CU_ASSERT_EQUAL(guac_mem_ckd_mul_or_die(0, 0), 0);
CU_ASSERT_EQUAL(guac_mem_ckd_mul_or_die(0, 0, 0), 0);
CU_ASSERT_EQUAL(guac_mem_ckd_mul_or_die(0, 0, 0, 0), 0);
CU_ASSERT_EQUAL(guac_mem_ckd_mul_or_die(0, 0, 0, 0, 0), 0);
CU_ASSERT_EQUAL(guac_mem_ckd_mul_or_die(0, 1), 0);
CU_ASSERT_EQUAL(guac_mem_ckd_mul_or_die(1, 0), 0);
CU_ASSERT_EQUAL(guac_mem_ckd_mul_or_die(3, 2, 0), 0);
CU_ASSERT_EQUAL(guac_mem_ckd_mul_or_die(5, 0, 8, 9), 0);
CU_ASSERT_EQUAL(guac_mem_ckd_mul_or_die(99, 99, 99, 0, 99), 0);
}
/**
* Test which verifies that guac_mem_ckd_mul_or_die() successfully calculates
* expected values for relatively small integer inputs.
*/
void test_mem__ckd_mul_or_die_small() {
CU_ASSERT_EQUAL(guac_mem_ckd_mul_or_die(123), 123);
CU_ASSERT_EQUAL(guac_mem_ckd_mul_or_die(123, 456), 123 * 456);
CU_ASSERT_EQUAL(guac_mem_ckd_mul_or_die(123, 456, 789), 123 * 456 * 789);
}
/**
* Test which verifies that guac_mem_ckd_mul_or_die() behaves as expected for
* relatively large integer inputs.
*/
void test_mem__ckd_mul_or_die_large() {
CU_ASSERT_EQUAL(guac_mem_ckd_mul_or_die(SIZE_MAX), SIZE_MAX);
ASSERT_SIGNALLED(SIGABRT, guac_mem_ckd_mul_or_die(123, 456, SIZE_MAX));
ASSERT_SIGNALLED(SIGABRT, guac_mem_ckd_mul_or_die(SIZE_MAX / 2, SIZE_MAX / 2));
}

View File

@ -0,0 +1,105 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <CUnit/CUnit.h>
#include <guacamole/mem.h>
#include <stdint.h>
/**
* Test which verifies that guac_mem_ckd_sub() calculates results correctly for
* all inputs involving at least one zero value.
*/
void test_mem__ckd_sub_zero() {
size_t result = SIZE_MAX;
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_sub(&result, 0));
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_sub(&result, 0, 0));
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_sub(&result, 0, 0, 0));
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_sub(&result, 0, 0, 0, 0));
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_sub(&result, 0, 0, 0, 0, 0));
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_sub(&result, 1, 0));
CU_ASSERT_EQUAL(result, 1);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_sub(&result, 3, 2, 0));
CU_ASSERT_EQUAL(result, 3 - 2);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_sub(&result, 8, 5, 0, 1));
CU_ASSERT_EQUAL(result, 8 - 5 - 1);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_sub(&result, 99, 99, 0));
CU_ASSERT_EQUAL(result, 0);
}
/**
* Test which verifies that guac_mem_ckd_sub() successfully calculates expected
* values for relatively small integer inputs, including inputs that cause
* overflow beyond zero.
*/
void test_mem__ckd_sub_small() {
size_t result = SIZE_MAX;
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_sub(&result, 123));
CU_ASSERT_EQUAL(result, 123);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_sub(&result, 456, 123));
CU_ASSERT_EQUAL(result, 456 - 123);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_sub(&result, 789, 456, 123));
CU_ASSERT_EQUAL(result, 789 - 456 - 123);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_sub(&result, 123, 123));
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_TRUE_FATAL(guac_mem_ckd_sub(&result, 123, 123, 1));
}
/**
* Test which verifies that guac_mem_ckd_sub() behaves as expected for
* relatively large integer inputs, including inputs that cause overflow beyond
* zero.
*/
void test_mem__ckd_sub_large() {
size_t result = 0;
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_sub(&result, SIZE_MAX));
CU_ASSERT_EQUAL(result, SIZE_MAX);
CU_ASSERT_FALSE_FATAL(guac_mem_ckd_sub(&result, SIZE_MAX, SIZE_MAX / 2));
CU_ASSERT_EQUAL(result, SIZE_MAX - (SIZE_MAX / 2));
CU_ASSERT_TRUE_FATAL(guac_mem_ckd_sub(&result, SIZE_MAX, SIZE_MAX, 1));
CU_ASSERT_TRUE_FATAL(guac_mem_ckd_sub(&result, 0, SIZE_MAX));
}

View File

@ -0,0 +1,74 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include "assert-signal.h"
#include <CUnit/CUnit.h>
#include <guacamole/mem.h>
#include <stdint.h>
/**
* Test which verifies that guac_mem_ckd_sub_or_die() calculates results
* correctly for all inputs involving at least one zero value.
*/
void test_mem__ckd_sub_or_die_zero() {
CU_ASSERT_EQUAL(guac_mem_ckd_sub_or_die(0), 0);
CU_ASSERT_EQUAL(guac_mem_ckd_sub_or_die(0, 0), 0);
CU_ASSERT_EQUAL(guac_mem_ckd_sub_or_die(0, 0, 0), 0);
CU_ASSERT_EQUAL(guac_mem_ckd_sub_or_die(0, 0, 0, 0), 0);
CU_ASSERT_EQUAL(guac_mem_ckd_sub_or_die(0, 0, 0, 0, 0), 0);
CU_ASSERT_EQUAL(guac_mem_ckd_sub_or_die(1, 0), 1);
CU_ASSERT_EQUAL(guac_mem_ckd_sub_or_die(3, 2, 0), 3 - 2);
CU_ASSERT_EQUAL(guac_mem_ckd_sub_or_die(8, 5, 0, 1), 8 - 5 - 1);
CU_ASSERT_EQUAL(guac_mem_ckd_sub_or_die(99, 99, 0), 0);
}
/**
* Test which verifies that guac_mem_ckd_sub_or_die() successfully calculates
* expected values for relatively small integer inputs, including inputs that
* cause overflow beyond zero.
*/
void test_mem__ckd_sub_or_die_small() {
CU_ASSERT_EQUAL(guac_mem_ckd_sub_or_die(123), 123);
CU_ASSERT_EQUAL(guac_mem_ckd_sub_or_die(456, 123), 456 - 123);
CU_ASSERT_EQUAL(guac_mem_ckd_sub_or_die(789, 456, 123), 789 - 456 - 123);
CU_ASSERT_EQUAL(guac_mem_ckd_sub_or_die(123, 123), 0);
ASSERT_SIGNALLED(SIGABRT, guac_mem_ckd_sub_or_die(123, 123, 1));
}
/**
* Test which verifies that guac_mem_ckd_sub_or_die() behaves as expected for
* relatively large integer inputs, including inputs that cause overflow beyond
* zero.
*/
void test_mem__ckd_sub_or_die_large() {
CU_ASSERT_EQUAL(guac_mem_ckd_sub_or_die(SIZE_MAX), SIZE_MAX);
CU_ASSERT_EQUAL(guac_mem_ckd_sub_or_die(SIZE_MAX, SIZE_MAX / 2), SIZE_MAX - (SIZE_MAX / 2));
ASSERT_SIGNALLED(SIGABRT, guac_mem_ckd_sub_or_die(SIZE_MAX, SIZE_MAX, 1));
ASSERT_SIGNALLED(SIGABRT, guac_mem_ckd_sub_or_die(0, SIZE_MAX));
}

View File

@ -0,0 +1,63 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <CUnit/CUnit.h>
#include <guacamole/mem.h>
#include <stdint.h>
/**
* Test which verifies that guac_mem_free() sets the provided pointer to NULL after
* freeing.
*/
void test_mem__free_assigns_null() {
void* ptr = guac_mem_alloc(123);
CU_ASSERT_PTR_NOT_NULL(ptr);
guac_mem_free(ptr);
CU_ASSERT_PTR_NULL(ptr);
}
/**
* Test which verifies that guac_mem_free_const() can be used to free constant
* pointers, but that those pointers are not set to NULL after freeing.
*/
void test_mem__free_const() {
const void* ptr = guac_mem_alloc(123);
CU_ASSERT_PTR_NOT_NULL(ptr);
guac_mem_free_const(ptr);
CU_ASSERT_PTR_NOT_NULL(ptr);
}
/**
* Test which verifies that guac_mem_free() does nothing if provided a NULL
* pointer.
*/
void test_mem__free_null() {
void* ptr = NULL;
guac_mem_free(ptr);
}
/**
* Test which verifies that guac_mem_free_const() does nothing if provided a NULL
* pointer.
*/
void test_mem__free_null_const() {
const void* ptr = NULL;
guac_mem_free_const(ptr);
}

View File

@ -0,0 +1,118 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <CUnit/CUnit.h>
#include <guacamole/mem.h>
#include <stdint.h>
/**
* Test which verifies that guac_mem_realloc() returns NULL for all inputs
* involving at least one zero value (reallocation to zero bytes is not an
* error but equivalent freeing the memory).
*/
void test_mem__realloc_success_zero() {
void* ptr;
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
CU_ASSERT_PTR_NULL(guac_mem_realloc(ptr, 0));
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
CU_ASSERT_PTR_NULL(guac_mem_realloc(ptr, 0, 0));
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
CU_ASSERT_PTR_NULL(guac_mem_realloc(ptr, 0, 0, 0));
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
CU_ASSERT_PTR_NULL(guac_mem_realloc(ptr, 0, 0, 0, 0));
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
CU_ASSERT_PTR_NULL(guac_mem_realloc(ptr, 0, 0, 0, 0, 0));
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
CU_ASSERT_PTR_NULL(guac_mem_realloc(ptr, 1, 0));
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
CU_ASSERT_PTR_NULL(guac_mem_realloc(ptr, 3, 2, 0));
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
CU_ASSERT_PTR_NULL(guac_mem_realloc(ptr, 5, 0, 8, 9));
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
CU_ASSERT_PTR_NULL(guac_mem_realloc(ptr, 99, 99, 99, 0, 99));
}
/**
* Test which verifies that guac_mem_realloc() successfully allocates blocks of
* memory for inputs that can reasonably be expected to succeed.
*/
void test_mem__realloc_success() {
void* ptr;
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
ptr = guac_mem_realloc(ptr, 123);
CU_ASSERT_PTR_NOT_NULL(ptr);
guac_mem_free(ptr);
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
ptr = guac_mem_realloc(ptr, 123, 456);
CU_ASSERT_PTR_NOT_NULL(ptr);
guac_mem_free(ptr);
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
ptr = guac_mem_realloc(ptr, 123, 456, 789);
CU_ASSERT_PTR_NOT_NULL(ptr);
guac_mem_free(ptr);
}
/**
* Test which verifies that guac_mem_realloc() fails to allocate blocks of
* memory that exceed the capacity of a size_t.
*/
void test_mem__realloc_fail_large() {
void* ptr;
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
CU_ASSERT_PTR_NULL(guac_mem_realloc(ptr, 123, 456, SIZE_MAX));
guac_mem_free(ptr);
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
CU_ASSERT_PTR_NULL(guac_mem_realloc(ptr, SIZE_MAX / 2, SIZE_MAX / 2));
guac_mem_free(ptr);
}

View File

@ -0,0 +1,120 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include "assert-signal.h"
#include <CUnit/CUnit.h>
#include <guacamole/mem.h>
#include <stdint.h>
/**
* Test which verifies that guac_mem_realloc_or_die() returns NULL for all
* inputs involving at least one zero value (reallocation to zero bytes is not
* an error but equivalent freeing the memory).
*/
void test_mem__realloc_or_die_success_zero() {
void* ptr;
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
CU_ASSERT_PTR_NULL(guac_mem_realloc_or_die(ptr, 0));
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
CU_ASSERT_PTR_NULL(guac_mem_realloc_or_die(ptr, 0, 0));
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
CU_ASSERT_PTR_NULL(guac_mem_realloc_or_die(ptr, 0, 0, 0));
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
CU_ASSERT_PTR_NULL(guac_mem_realloc_or_die(ptr, 0, 0, 0, 0));
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
CU_ASSERT_PTR_NULL(guac_mem_realloc_or_die(ptr, 0, 0, 0, 0, 0));
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
CU_ASSERT_PTR_NULL(guac_mem_realloc_or_die(ptr, 1, 0));
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
CU_ASSERT_PTR_NULL(guac_mem_realloc_or_die(ptr, 3, 2, 0));
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
CU_ASSERT_PTR_NULL(guac_mem_realloc_or_die(ptr, 5, 0, 8, 9));
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
CU_ASSERT_PTR_NULL(guac_mem_realloc_or_die(ptr, 99, 99, 99, 0, 99));
}
/**
* Test which verifies that guac_mem_realloc_or_die() successfully allocates
* blocks of memory for inputs that can reasonably be expected to succeed.
*/
void test_mem__realloc_or_die_success() {
void* ptr;
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
ptr = guac_mem_realloc_or_die(ptr, 123);
CU_ASSERT_PTR_NOT_NULL(ptr);
guac_mem_free(ptr);
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
ptr = guac_mem_realloc_or_die(ptr, 123, 456);
CU_ASSERT_PTR_NOT_NULL(ptr);
guac_mem_free(ptr);
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
ptr = guac_mem_realloc_or_die(ptr, 123, 456, 789);
CU_ASSERT_PTR_NOT_NULL(ptr);
guac_mem_free(ptr);
}
/**
* Test which verifies that guac_mem_realloc_or_die() fails to allocate blocks of
* memory that exceed the capacity of a size_t.
*/
void test_mem__realloc_or_die_fail_large() {
void* ptr;
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
ASSERT_SIGNALLED(SIGABRT, guac_mem_realloc_or_die(ptr, 123, 456, SIZE_MAX));
guac_mem_free(ptr);
ptr = guac_mem_alloc(1);
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
ASSERT_SIGNALLED(SIGABRT, guac_mem_realloc_or_die(ptr, SIZE_MAX / 2, SIZE_MAX / 2));
guac_mem_free(ptr);
}

View File

@ -0,0 +1,102 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <CUnit/CUnit.h>
#include <guacamole/mem.h>
#include <stdint.h>
/**
* Test which verifies that guac_mem_zalloc() returns NULL for all inputs involving
* at least one zero value.
*/
void test_mem__zalloc_fail_zero() {
CU_ASSERT_PTR_NULL(guac_mem_zalloc(0));
CU_ASSERT_PTR_NULL(guac_mem_zalloc(0, 0));
CU_ASSERT_PTR_NULL(guac_mem_zalloc(0, 0, 0));
CU_ASSERT_PTR_NULL(guac_mem_zalloc(0, 0, 0, 0));
CU_ASSERT_PTR_NULL(guac_mem_zalloc(0, 0, 0, 0, 0));
CU_ASSERT_PTR_NULL(guac_mem_zalloc(1, 0));
CU_ASSERT_PTR_NULL(guac_mem_zalloc(3, 2, 0));
CU_ASSERT_PTR_NULL(guac_mem_zalloc(5, 0, 8, 9));
CU_ASSERT_PTR_NULL(guac_mem_zalloc(99, 99, 99, 0, 99));
}
/**
* Returns whether all bytes within the given memory region are zero.
*
* @param ptr
* The first byte of the memory region to test.
*
* @param length
* The number of bytes within the memory region.
*
* @returns
* Non-zero if all bytes within the memory region have the value of zero,
* zero otherwise.
*/
static int is_all_zeroes(void* ptr, size_t length) {
int result = 0;
unsigned char* current = (unsigned char*) ptr;
for (size_t i = 0; i < length; i++)
result |= *(current++);
return !result;
}
/**
* Test which verifies that guac_mem_zalloc() successfully allocates blocks of
* memory for inputs that can reasonably be expected to succeed, and that each
* block is zeroed out.
*/
void test_mem__zalloc_success() {
void* ptr;
ptr = guac_mem_zalloc(123);
CU_ASSERT_PTR_NOT_NULL(ptr);
CU_ASSERT(is_all_zeroes(ptr, 123));
guac_mem_free(ptr);
ptr = guac_mem_zalloc(123, 456);
CU_ASSERT_PTR_NOT_NULL(ptr);
CU_ASSERT(is_all_zeroes(ptr, 123 * 456));
guac_mem_free(ptr);
ptr = guac_mem_zalloc(123, 456, 789);
CU_ASSERT_PTR_NOT_NULL(ptr);
CU_ASSERT(is_all_zeroes(ptr, 123 * 456 * 789));
guac_mem_free(ptr);
}
/**
* Test which verifies that guac_mem_zalloc() fails to allocate blocks of memory
* that exceed the capacity of a size_t.
*/
void test_mem__zalloc_fail_large() {
CU_ASSERT_PTR_NULL(guac_mem_zalloc(123, 456, SIZE_MAX));
CU_ASSERT_PTR_NULL(guac_mem_zalloc(SIZE_MAX / 2, SIZE_MAX / 2));
}

View File

@ -18,6 +18,7 @@
*/
#include <CUnit/CUnit.h>
#include <guacamole/mem.h>
#include <guacamole/string.h>
#include <stdlib.h>
@ -46,4 +47,6 @@ void test_string__strdup() {
CU_ASSERT_STRING_EQUAL(dest_string, "Mashing avocados.");
CU_ASSERT_PTR_NULL(null_copy);
}
guac_mem_free(dest_string);
}

View File

@ -19,10 +19,12 @@
#include "config.h"
#include "guacamole/mem.h"
#include "guacamole/client.h"
#include "guacamole/object.h"
#include "guacamole/protocol.h"
#include "guacamole/stream.h"
#include "guacamole/string.h"
#include "guacamole/timestamp.h"
#include "guacamole/user.h"
#include "user-handlers.h"
@ -680,11 +682,11 @@ int __guac_handshake_image_handler(guac_user* user, int argc, char** argv) {
int __guac_handshake_name_handler(guac_user* user, int argc, char** argv) {
/* Free any past value for the user's name */
free((char *) user->info.name);
guac_mem_free_const(user->info.name);
/* If a value is provided for the name, copy it into guac_user. */
if (argc > 0 && strcmp(argv[0], ""))
user->info.name = (const char*) strdup(argv[0]);
user->info.name = (const char*) guac_strdup(argv[0]);
/* No or empty value was provided, so make sure this is NULLed out. */
else
@ -697,11 +699,11 @@ int __guac_handshake_name_handler(guac_user* user, int argc, char** argv) {
int __guac_handshake_timezone_handler(guac_user* user, int argc, char** argv) {
/* Free any past value */
free((char *) user->info.timezone);
guac_mem_free_const(user->info.timezone);
/* Store timezone, if present */
if (argc > 0 && strcmp(argv[0], ""))
user->info.timezone = (const char*) strdup(argv[0]);
user->info.timezone = (const char*) guac_strdup(argv[0]);
else
user->info.timezone = NULL;
@ -715,11 +717,12 @@ char** guac_copy_mimetypes(char** mimetypes, int count) {
int i;
/* Allocate sufficient space for NULL-terminated array of mimetypes */
char** mimetypes_copy = malloc(sizeof(char*) * (count+1));
char** mimetypes_copy = guac_mem_alloc(sizeof(char*),
guac_mem_ckd_add_or_die(count, 1));
/* Copy each provided mimetype */
for (i = 0; i < count; i++)
mimetypes_copy[i] = strdup(mimetypes[i]);
mimetypes_copy[i] = guac_strdup(mimetypes[i]);
/* Terminate with NULL */
mimetypes_copy[count] = NULL;
@ -737,12 +740,12 @@ void guac_free_mimetypes(char** mimetypes) {
/* Free all strings within NULL-terminated mimetype array */
while (*current_mimetype != NULL) {
free(*current_mimetype);
guac_mem_free(*current_mimetype);
current_mimetype++;
}
/* Free the array itself, now that its contents have been freed */
free(mimetypes);
guac_mem_free(mimetypes);
}

View File

@ -19,6 +19,7 @@
#include "config.h"
#include "guacamole/mem.h"
#include "guacamole/client.h"
#include "guacamole/error.h"
#include "guacamole/parser.h"
@ -372,8 +373,8 @@ int guac_user_handle_connection(guac_user* user, int usec_timeout) {
guac_free_mimetypes((char **) user->info.video_mimetypes);
/* Free name and timezone info. */
free((char *) user->info.name);
free((char *) user->info.timezone);
guac_mem_free_const(user->info.name);
guac_mem_free_const(user->info.timezone);
guac_parser_free(parser);

View File

@ -22,12 +22,14 @@
#include "encode-jpeg.h"
#include "encode-png.h"
#include "encode-webp.h"
#include "guacamole/mem.h"
#include "guacamole/client.h"
#include "guacamole/object.h"
#include "guacamole/pool.h"
#include "guacamole/protocol.h"
#include "guacamole/socket.h"
#include "guacamole/stream.h"
#include "guacamole/string.h"
#include "guacamole/timestamp.h"
#include "guacamole/user.h"
#include "id.h"
@ -40,13 +42,13 @@
guac_user* guac_user_alloc() {
guac_user* user = calloc(1, sizeof(guac_user));
guac_user* user = guac_mem_zalloc(sizeof(guac_user));
int i;
/* Generate ID */
user->user_id = guac_generate_id(GUAC_USER_ID_PREFIX);
if (user->user_id == NULL) {
free(user);
guac_mem_free(user);
return NULL;
}
@ -59,8 +61,8 @@ guac_user* guac_user_alloc() {
user->__stream_pool = guac_pool_alloc(0);
/* Initialze streams */
user->__input_streams = malloc(sizeof(guac_stream) * GUAC_USER_MAX_STREAMS);
user->__output_streams = malloc(sizeof(guac_stream) * GUAC_USER_MAX_STREAMS);
user->__input_streams = guac_mem_alloc(sizeof(guac_stream), GUAC_USER_MAX_STREAMS);
user->__output_streams = guac_mem_alloc(sizeof(guac_stream), GUAC_USER_MAX_STREAMS);
for (i=0; i<GUAC_USER_MAX_STREAMS; i++) {
user->__input_streams[i].index = GUAC_USER_CLOSED_STREAM_INDEX;
@ -71,7 +73,7 @@ guac_user* guac_user_alloc() {
user->__object_pool = guac_pool_alloc(0);
/* Initialize objects */
user->__objects = malloc(sizeof(guac_object) * GUAC_USER_MAX_OBJECTS);
user->__objects = guac_mem_alloc(sizeof(guac_object), GUAC_USER_MAX_OBJECTS);
for (i=0; i<GUAC_USER_MAX_OBJECTS; i++)
user->__objects[i].index = GUAC_USER_UNDEFINED_OBJECT_INDEX;
@ -82,21 +84,21 @@ guac_user* guac_user_alloc() {
void guac_user_free(guac_user* user) {
/* Free streams */
free(user->__input_streams);
free(user->__output_streams);
guac_mem_free(user->__input_streams);
guac_mem_free(user->__output_streams);
/* Free stream pool */
guac_pool_free(user->__stream_pool);
/* Free objects */
free(user->__objects);
guac_mem_free(user->__objects);
/* Free object pool */
guac_pool_free(user->__object_pool);
/* Clean up user */
free(user->user_id);
free(user);
guac_mem_free(user->user_id);
guac_mem_free(user);
}
@ -377,12 +379,12 @@ char* guac_user_parse_args_string(guac_user* user, const char** arg_names,
guac_user_log(user, GUAC_LOG_DEBUG, "Parameter \"%s\" omitted. Using "
"default value of \"%s\".", arg_names[index], default_value);
return strdup(default_value);
return guac_strdup(default_value);
}
/* Otherwise use provided value */
return strdup(value);
return guac_strdup(value);
}

View File

@ -25,6 +25,7 @@
#include <guacamole/argv.h>
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <guacamole/socket.h>
#include <libwebsockets.h>
@ -120,7 +121,7 @@ int guac_client_init(guac_client* client) {
client->args = GUAC_KUBERNETES_CLIENT_ARGS;
/* Allocate client instance data */
guac_kubernetes_client* kubernetes_client = calloc(1, sizeof(guac_kubernetes_client));
guac_kubernetes_client* kubernetes_client = guac_mem_zalloc(sizeof(guac_kubernetes_client));
client->data = kubernetes_client;
/* Set handlers */
@ -159,7 +160,7 @@ int guac_kubernetes_client_free_handler(guac_client* client) {
if (kubernetes_client->settings != NULL)
guac_kubernetes_settings_free(kubernetes_client->settings);
free(kubernetes_client);
guac_mem_free(kubernetes_client);
return 0;
}

View File

@ -28,6 +28,7 @@
#include "url.h"
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <guacamole/protocol.h>
#include <guacamole/recording.h>
#include <libwebsockets.h>
@ -255,7 +256,7 @@ void* guac_kubernetes_client_thread(void* data) {
kubernetes_client->term = guac_terminal_create(client, options);
/* Free options struct now that it's been used */
free(options);
guac_mem_free(options);
/* Fail if terminal init failed */
if (kubernetes_client->term == NULL) {

View File

@ -21,6 +21,7 @@
#include "settings.h"
#include "terminal/terminal.h"
#include <guacamole/mem.h>
#include <guacamole/user.h>
#include <stdlib.h>
@ -255,7 +256,7 @@ guac_kubernetes_settings* guac_kubernetes_parse_args(guac_user* user,
}
guac_kubernetes_settings* settings =
calloc(1, sizeof(guac_kubernetes_settings));
guac_mem_zalloc(sizeof(guac_kubernetes_settings));
/* Read hostname */
settings->hostname =
@ -411,35 +412,35 @@ guac_kubernetes_settings* guac_kubernetes_parse_args(guac_user* user,
void guac_kubernetes_settings_free(guac_kubernetes_settings* settings) {
/* Free network connection information */
free(settings->hostname);
guac_mem_free(settings->hostname);
/* Free Kubernetes pod/container details */
free(settings->kubernetes_namespace);
free(settings->kubernetes_pod);
free(settings->kubernetes_container);
guac_mem_free(settings->kubernetes_namespace);
guac_mem_free(settings->kubernetes_pod);
guac_mem_free(settings->kubernetes_container);
/* Free Kubernetes exec command */
free(settings->exec_command);
guac_mem_free(settings->exec_command);
/* Free SSL/TLS details */
free(settings->client_cert);
free(settings->client_key);
free(settings->ca_cert);
guac_mem_free(settings->client_cert);
guac_mem_free(settings->client_key);
guac_mem_free(settings->ca_cert);
/* Free display preferences */
free(settings->font_name);
free(settings->color_scheme);
guac_mem_free(settings->font_name);
guac_mem_free(settings->color_scheme);
/* Free typescript settings */
free(settings->typescript_name);
free(settings->typescript_path);
guac_mem_free(settings->typescript_name);
guac_mem_free(settings->typescript_path);
/* Free screen recording settings */
free(settings->recording_name);
free(settings->recording_path);
guac_mem_free(settings->recording_name);
guac_mem_free(settings->recording_path);
/* Free overall structure */
free(settings);
guac_mem_free(settings);
}

View File

@ -22,8 +22,10 @@
#include "rdp.h"
#include "settings.h"
#include <guacamole/mem.h>
#include <guacamole/protocol.h>
#include <guacamole/socket.h>
#include <guacamole/string.h>
#include <guacamole/user.h>
#include <pthread.h>
@ -39,22 +41,22 @@ int guac_rdp_argv_callback(guac_user* user, const char* mimetype,
/* Update username */
if (strcmp(name, GUAC_RDP_ARGV_USERNAME) == 0) {
free(settings->username);
settings->username = strdup(value);
guac_mem_free(settings->username);
settings->username = guac_strdup(value);
}
/* Update password */
else if (strcmp(name, GUAC_RDP_ARGV_PASSWORD) == 0) {
free(settings->password);
settings->password = strdup(value);
guac_mem_free(settings->password);
settings->password = guac_strdup(value);
}
/* Update domain */
else if (strcmp(name, GUAC_RDP_ARGV_DOMAIN) == 0) {
free(settings->domain);
settings->domain = strdup(value);
guac_mem_free(settings->domain);
settings->domain = guac_strdup(value);
}
return 0;
}
}

View File

@ -24,6 +24,7 @@
#include <freerdp/freerdp.h>
#include <guacamole/audio.h>
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <winpr/wtypes.h>
#include <inttypes.h>
@ -93,14 +94,14 @@ static void guac_rdp_beep_fill_triangle_wave(unsigned char* buffer,
static void guac_rdp_beep_write_pcm(guac_audio_stream* audio,
int frequency, int duration) {
int buffer_size = audio->rate * duration / 1000;
unsigned char* buffer = malloc(buffer_size);
size_t buffer_size = guac_mem_ckd_mul_or_die(audio->rate, duration) / 1000;
unsigned char* buffer = guac_mem_alloc(buffer_size);
/* Beep for given frequency/duration using a simple triangle wave */
guac_rdp_beep_fill_triangle_wave(buffer, frequency, audio->rate, buffer_size);
guac_audio_stream_write_pcm(audio, buffer, buffer_size);
free(buffer);
guac_mem_free(buffer);
}

View File

@ -21,6 +21,7 @@
#include "rdp.h"
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <guacamole/protocol.h>
#include <guacamole/socket.h>
#include <guacamole/stream.h>
@ -116,8 +117,8 @@ static int guac_rdp_audio_buffer_duration(const guac_rdp_audio_format* format, i
* The number of bytes required to store audio data in the given format
* covering the given length of time.
*/
static int guac_rdp_audio_buffer_length(const guac_rdp_audio_format* format, int duration) {
return duration * format->rate * format->bps * format->channels / 1000;
static size_t guac_rdp_audio_buffer_length(const guac_rdp_audio_format* format, int duration) {
return guac_mem_ckd_mul_or_die(duration, format->rate, format->bps, format->channels) / 1000;
}
/**
@ -261,7 +262,7 @@ static void* guac_rdp_audio_buffer_flush_thread(void* data) {
guac_rdp_audio_buffer* guac_rdp_audio_buffer_alloc(guac_client* client) {
guac_rdp_audio_buffer* buffer = calloc(1, sizeof(guac_rdp_audio_buffer));
guac_rdp_audio_buffer* buffer = guac_mem_zalloc(sizeof(guac_rdp_audio_buffer));
pthread_mutex_init(&(buffer->lock), NULL);
pthread_cond_init(&(buffer->modified), NULL);
@ -395,21 +396,23 @@ void guac_rdp_audio_buffer_begin(guac_rdp_audio_buffer* audio_buffer,
audio_buffer->data = data;
/* Calculate size of each packet in bytes */
audio_buffer->packet_size = packet_frames
* audio_buffer->out_format.channels
* audio_buffer->out_format.bps;
audio_buffer->packet_size = guac_mem_ckd_mul_or_die(packet_frames,
audio_buffer->out_format.channels,
audio_buffer->out_format.bps);
/* Ensure outbound buffer includes enough space for at least 250ms of
* audio */
int ideal_size = guac_rdp_audio_buffer_length(&audio_buffer->out_format,
size_t ideal_size = guac_rdp_audio_buffer_length(&audio_buffer->out_format,
GUAC_RDP_AUDIO_BUFFER_MIN_DURATION);
/* Round up to nearest whole packet */
int ideal_packets = (ideal_size + audio_buffer->packet_size - 1) / audio_buffer->packet_size;
size_t ideal_packets = guac_mem_ckd_sub_or_die(
guac_mem_ckd_add_or_die(ideal_size, audio_buffer->packet_size), 1
) / audio_buffer->packet_size;
/* Allocate new buffer */
audio_buffer->packet_buffer_size = ideal_packets * audio_buffer->packet_size;
audio_buffer->packet = malloc(audio_buffer->packet_buffer_size);
audio_buffer->packet_buffer_size = guac_mem_ckd_mul_or_die(ideal_packets, audio_buffer->packet_size);
audio_buffer->packet = guac_mem_alloc(audio_buffer->packet_buffer_size);
guac_client_log(audio_buffer->client, GUAC_LOG_DEBUG, "Output buffer for "
"audio input is %i bytes (up to %i ms).", audio_buffer->packet_buffer_size,
@ -609,8 +612,7 @@ void guac_rdp_audio_buffer_end(guac_rdp_audio_buffer* audio_buffer) {
audio_buffer->total_bytes_received = 0;
/* Free packet (if any) */
free(audio_buffer->packet);
audio_buffer->packet = NULL;
guac_mem_free(audio_buffer->packet);
pthread_cond_broadcast(&(audio_buffer->modified));
pthread_mutex_unlock(&(audio_buffer->lock));
@ -632,7 +634,7 @@ void guac_rdp_audio_buffer_free(guac_rdp_audio_buffer* audio_buffer) {
pthread_mutex_destroy(&(audio_buffer->lock));
pthread_cond_destroy(&(audio_buffer->modified));
free(audio_buffer);
guac_mem_free(audio_buffer);
}

View File

@ -132,12 +132,12 @@ struct guac_rdp_audio_buffer {
* The size that each audio packet must be, in bytes. The packet buffer
* within this structure will be at least this size.
*/
int packet_size;
size_t packet_size;
/**
* The total number of bytes available within the packet buffer.
*/
int packet_buffer_size;
size_t packet_buffer_size;
/**
* The number of bytes currently stored within the packet buffer.

View File

@ -29,6 +29,7 @@
#include <freerdp/event.h>
#include <freerdp/freerdp.h>
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <guacamole/stream.h>
#include <guacamole/user.h>
#include <winpr/wtsapi.h>
@ -358,7 +359,7 @@ static UINT guac_rdp_cliprdr_format_data_request(CliprdrClientContext* cliprdr,
guac_iconv_write* remote_writer;
const char* input = clipboard->clipboard->buffer;
char* output = malloc(GUAC_COMMON_CLIPBOARD_MAX_LENGTH);
char* output = guac_mem_alloc(GUAC_COMMON_CLIPBOARD_MAX_LENGTH);
/* Map requested clipboard format to a guac_iconv writer */
switch (format_data_request->requestedFormatId) {
@ -379,7 +380,7 @@ static UINT guac_rdp_cliprdr_format_data_request(CliprdrClientContext* cliprdr,
"server has requested a clipboard format which was not "
"declared as available. This violates the specification "
"for the CLIPRDR channel.");
free(output);
guac_mem_free(output);
return CHANNEL_RC_OK;
}
@ -403,7 +404,7 @@ static UINT guac_rdp_cliprdr_format_data_request(CliprdrClientContext* cliprdr,
UINT result = cliprdr->ClientFormatDataResponse(cliprdr, &data_response);
pthread_mutex_unlock(&(rdp_client->message_lock));
free(start);
guac_mem_free(start);
return result;
}
@ -593,7 +594,7 @@ static void guac_rdp_cliprdr_channel_disconnected(rdpContext* context,
guac_rdp_clipboard* guac_rdp_clipboard_alloc(guac_client* client) {
/* Allocate clipboard and underlying storage */
guac_rdp_clipboard* clipboard = calloc(1, sizeof(guac_rdp_clipboard));
guac_rdp_clipboard* clipboard = guac_mem_zalloc(sizeof(guac_rdp_clipboard));
clipboard->client = client;
clipboard->clipboard = guac_common_clipboard_alloc();
clipboard->requested_format = CF_TEXT;
@ -637,7 +638,7 @@ void guac_rdp_clipboard_free(guac_rdp_clipboard* clipboard) {
/* Free clipboard and underlying storage */
guac_common_clipboard_free(clipboard->clipboard);
free(clipboard);
guac_mem_free(clipboard);
}

View File

@ -23,6 +23,7 @@
#include <freerdp/settings.h>
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <guacamole/string.h>
#include <winpr/stream.h>
#include <winpr/wtsapi.h>
@ -38,7 +39,7 @@ int guac_rdp_common_svc_load_plugin(rdpContext* context,
guac_client* client = ((rdp_freerdp_context*) context)->client;
guac_rdp_common_svc* svc = calloc(1, sizeof(guac_rdp_common_svc));
guac_rdp_common_svc* svc = guac_mem_zalloc(sizeof(guac_rdp_common_svc));
svc->client = client;
svc->name = svc->_channel_def.name;
svc->_connect_handler = connect_handler;
@ -65,7 +66,7 @@ int guac_rdp_common_svc_load_plugin(rdpContext* context,
guac_client_log(client, GUAC_LOG_WARNING, "Cannot create static "
"channel \"%s\": failed to load \"guac-common-svc\" plugin "
"for FreeRDP.", svc->name);
free(svc);
guac_mem_free(svc);
}
/* Store and log on success (SVC structure will be freed on channel termination) */

View File

@ -27,6 +27,7 @@
#include <freerdp/freerdp.h>
#include <freerdp/event.h>
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <guacamole/timestamp.h>
#include <stdlib.h>
@ -34,7 +35,7 @@
guac_rdp_disp* guac_rdp_disp_alloc(guac_client* client) {
guac_rdp_disp* disp = malloc(sizeof(guac_rdp_disp));
guac_rdp_disp* disp = guac_mem_alloc(sizeof(guac_rdp_disp));
disp->client = client;
/* Not yet connected */
@ -51,7 +52,7 @@ guac_rdp_disp* guac_rdp_disp_alloc(guac_client* client) {
}
void guac_rdp_disp_free(guac_rdp_disp* disp) {
free(disp);
guac_mem_free(disp);
}
/**

View File

@ -24,6 +24,7 @@
#include <freerdp/settings.h>
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <guacamole/protocol.h>
#include <guacamole/socket.h>
#include <guacamole/stream.h>
@ -172,7 +173,7 @@ int guac_rdp_pipe_svc_blob_handler(guac_user* user, guac_stream* stream,
void guac_rdp_pipe_svc_process_connect(guac_rdp_common_svc* svc) {
/* Associate SVC with new Guacamole pipe */
guac_rdp_pipe_svc* pipe_svc = malloc(sizeof(guac_rdp_pipe_svc));
guac_rdp_pipe_svc* pipe_svc = guac_mem_alloc(sizeof(guac_rdp_pipe_svc));
pipe_svc->svc = svc;
pipe_svc->output_pipe = guac_client_alloc_stream(svc->client);
svc->data = pipe_svc;
@ -214,7 +215,7 @@ void guac_rdp_pipe_svc_process_terminate(guac_rdp_common_svc* svc) {
/* Remove and free SVC */
guac_rdp_pipe_svc_remove(svc->client, svc->name);
free(pipe_svc);
guac_mem_free(pipe_svc);
}

View File

@ -29,6 +29,7 @@
#include <freerdp/channels/rdpdr.h>
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <winpr/nt.h>
#include <winpr/stream.h>
#include <winpr/wtypes.h>
@ -165,7 +166,7 @@ void guac_rdpdr_fs_process_read(guac_rdp_common_svc* svc,
length = GUAC_RDP_MAX_READ_BUFFER;
/* Allocate buffer */
buffer = malloc(length);
buffer = guac_mem_alloc(length);
/* Attempt read */
bytes_read = guac_rdp_fs_read((guac_rdp_fs*) device->data,
@ -187,7 +188,7 @@ void guac_rdpdr_fs_process_read(guac_rdp_common_svc* svc,
}
guac_rdp_common_svc_write(svc, output_stream);
free(buffer);
guac_mem_free(buffer);
}

View File

@ -28,6 +28,7 @@
#include <freerdp/freerdp.h>
#include <freerdp/settings.h>
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <winpr/stream.h>
#include <stdlib.h>
@ -145,7 +146,7 @@ void guac_rdpdr_process_connect(guac_rdp_common_svc* svc) {
guac_client* client = svc->client;
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
guac_rdpdr* rdpdr = (guac_rdpdr*) calloc(1, sizeof(guac_rdpdr));
guac_rdpdr* rdpdr = (guac_rdpdr*) guac_mem_zalloc(sizeof(guac_rdpdr));
svc->data = rdpdr;
/* Register printer if enabled */
@ -173,7 +174,7 @@ void guac_rdpdr_process_terminate(guac_rdp_common_svc* svc) {
device->free_handler(svc, device);
}
free(rdpdr);
guac_mem_free(svc->data); /* rdpdr */
}

View File

@ -27,6 +27,7 @@
#include <freerdp/freerdp.h>
#include <freerdp/event.h>
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <guacamole/timestamp.h>
#include <stdlib.h>
@ -34,7 +35,7 @@
guac_rdp_rdpei* guac_rdp_rdpei_alloc(guac_client* client) {
guac_rdp_rdpei* rdpei = malloc(sizeof(guac_rdp_rdpei));
guac_rdp_rdpei* rdpei = guac_mem_alloc(sizeof(guac_rdp_rdpei));
rdpei->client = client;
/* Not yet connected */
@ -49,7 +50,7 @@ guac_rdp_rdpei* guac_rdp_rdpei_alloc(guac_client* client) {
}
void guac_rdp_rdpei_free(guac_rdp_rdpei* rdpei) {
free(rdpei);
guac_mem_free(rdpei);
}
/**

View File

@ -25,6 +25,7 @@
#include <freerdp/codec/audio.h>
#include <freerdp/freerdp.h>
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <winpr/stream.h>
#include <stdlib.h>
@ -86,14 +87,13 @@ void guac_rdpsnd_process_receive(guac_rdp_common_svc* svc,
void guac_rdpsnd_process_connect(guac_rdp_common_svc* svc) {
guac_rdpsnd* rdpsnd = (guac_rdpsnd*) calloc(1, sizeof(guac_rdpsnd));
guac_rdpsnd* rdpsnd = (guac_rdpsnd*) guac_mem_zalloc(sizeof(guac_rdpsnd));
svc->data = rdpsnd;
}
void guac_rdpsnd_process_terminate(guac_rdp_common_svc* svc) {
guac_rdpsnd* rdpsnd = (guac_rdpsnd*) svc->data;
free(rdpsnd);
guac_mem_free(svc->data);
}
void guac_rdpsnd_load_plugin(rdpContext* context) {

View File

@ -37,6 +37,7 @@
#include <guacamole/audio.h>
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <guacamole/recording.h>
#include <dirent.h>
@ -194,7 +195,7 @@ int guac_client_init(guac_client* client, int argc, char** argv) {
client->args = GUAC_RDP_CLIENT_ARGS;
/* Alloc client data */
guac_rdp_client* rdp_client = calloc(1, sizeof(guac_rdp_client));
guac_rdp_client* rdp_client = guac_mem_zalloc(sizeof(guac_rdp_client));
client->data = rdp_client;
/* Init clipboard */
@ -296,7 +297,7 @@ int guac_rdp_client_free_handler(guac_client* client) {
pthread_mutex_destroy(&(rdp_client->message_lock));
/* Free client data */
free(rdp_client);
guac_mem_free(rdp_client);
return 0;

View File

@ -24,6 +24,7 @@
#include "rdp.h"
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <guacamole/object.h>
#include <guacamole/protocol.h>
#include <guacamole/socket.h>
@ -72,7 +73,7 @@ int guac_rdp_download_ack_handler(guac_user* user, guac_stream* stream,
else if (bytes_read == 0) {
guac_protocol_send_end(user->socket, stream);
guac_user_free_stream(user, stream);
free(download_status);
guac_mem_free(download_status);
}
/* Otherwise, fail stream */
@ -81,7 +82,7 @@ int guac_rdp_download_ack_handler(guac_user* user, guac_stream* stream,
"Error reading file for download");
guac_protocol_send_end(user->socket, stream);
guac_user_free_stream(user, stream);
free(download_status);
guac_mem_free(download_status);
}
guac_socket_flush(user->socket);
@ -128,7 +129,7 @@ int guac_rdp_download_get_handler(guac_user* user, guac_object* object,
if (file->attributes & FILE_ATTRIBUTE_DIRECTORY) {
/* Create stream data */
guac_rdp_ls_status* ls_status = malloc(sizeof(guac_rdp_ls_status));
guac_rdp_ls_status* ls_status = guac_mem_alloc(sizeof(guac_rdp_ls_status));
ls_status->fs = fs;
ls_status->file_id = file_id;
guac_strlcpy(ls_status->directory_name, name,
@ -153,7 +154,7 @@ int guac_rdp_download_get_handler(guac_user* user, guac_object* object,
else if (!fs->disable_download) {
/* Create stream data */
guac_rdp_download_status* download_status = malloc(sizeof(guac_rdp_download_status));
guac_rdp_download_status* download_status = guac_mem_alloc(sizeof(guac_rdp_download_status));
download_status->file_id = file_id;
download_status->offset = 0;
@ -209,7 +210,7 @@ void* guac_rdp_download_to_user(guac_user* user, void* data) {
/* Associate stream with transfer status */
guac_stream* stream = guac_user_alloc_stream(user);
guac_rdp_download_status* download_status = malloc(sizeof(guac_rdp_download_status));
guac_rdp_download_status* download_status = guac_mem_alloc(sizeof(guac_rdp_download_status));
stream->data = download_status;
stream->ack_handler = guac_rdp_download_ack_handler;
download_status->file_id = file_id;

View File

@ -22,6 +22,7 @@
#include "upload.h"
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <guacamole/object.h>
#include <guacamole/pool.h>
#include <guacamole/protocol.h>
@ -59,10 +60,10 @@ guac_rdp_fs* guac_rdp_fs_alloc(guac_client* client, const char* drive_path,
}
}
guac_rdp_fs* fs = malloc(sizeof(guac_rdp_fs));
guac_rdp_fs* fs = guac_mem_alloc(sizeof(guac_rdp_fs));
fs->client = client;
fs->drive_path = strdup(drive_path);
fs->drive_path = guac_strdup(drive_path);
fs->file_id_pool = guac_pool_alloc(0);
fs->open_files = 0;
fs->disable_download = disable_download;
@ -74,8 +75,8 @@ guac_rdp_fs* guac_rdp_fs_alloc(guac_client* client, const char* drive_path,
void guac_rdp_fs_free(guac_rdp_fs* fs) {
guac_pool_free(fs->file_id_pool);
free(fs->drive_path);
free(fs);
guac_mem_free(fs->drive_path);
guac_mem_free(fs);
}
guac_object* guac_rdp_fs_alloc_object(guac_rdp_fs* fs, guac_user* user) {
@ -366,8 +367,8 @@ int guac_rdp_fs_open(guac_rdp_fs* fs, const char* path,
file->fd = fd;
file->dir = NULL;
file->dir_pattern[0] = '\0';
file->absolute_path = strdup(normalized_path);
file->real_path = strdup(real_path);
file->absolute_path = guac_strdup(normalized_path);
file->real_path = guac_strdup(real_path);
file->bytes_written = 0;
guac_client_log(fs->client, GUAC_LOG_DEBUG,
@ -574,8 +575,8 @@ void guac_rdp_fs_close(guac_rdp_fs* fs, int file_id) {
close(file->fd);
/* Free name */
free(file->absolute_path);
free(file->real_path);
guac_mem_free(file->absolute_path);
guac_mem_free(file->real_path);
/* Free ID back to pool */
guac_pool_free_int(fs->file_id_pool, file_id);

View File

@ -25,6 +25,7 @@
#include <freerdp/freerdp.h>
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <winpr/wtypes.h>
#include <stdint.h>
@ -48,7 +49,7 @@ BOOL guac_rdp_glyph_new(rdpContext* context, const rdpGlyph* glyph) {
/* Init Cairo buffer */
stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
image_buffer = malloc(height*stride);
image_buffer = guac_mem_alloc(height, stride);
image_buffer_row = image_buffer;
/* Copy image data from image data to buffer */
@ -118,7 +119,7 @@ void guac_rdp_glyph_free(rdpContext* context, rdpGlyph* glyph) {
/* Free surface */
cairo_surface_destroy(((guac_rdp_glyph*) glyph)->surface);
free(image_buffer);
guac_mem_free(image_buffer);
/* NOTE: FreeRDP-allocated memory for the rdpGlyph will NOT be
* automatically released after this free handler is invoked, thus we must

View File

@ -25,6 +25,7 @@
#include <freerdp/freerdp.h>
#include <freerdp/input.h>
#include <guacamole/client.h>
#include <guacamole/mem.h>
#include <stdlib.h>
@ -440,7 +441,7 @@ static void guac_rdp_keyboard_load_keymap(guac_rdp_keyboard* keyboard,
guac_rdp_keyboard* guac_rdp_keyboard_alloc(guac_client* client,
const guac_rdp_keymap* keymap) {
guac_rdp_keyboard* keyboard = calloc(1, sizeof(guac_rdp_keyboard));
guac_rdp_keyboard* keyboard = guac_mem_zalloc(sizeof(guac_rdp_keyboard));
keyboard->client = client;
/* Load keymap into keyboard */
@ -451,7 +452,7 @@ guac_rdp_keyboard* guac_rdp_keyboard_alloc(guac_client* client,
}
void guac_rdp_keyboard_free(guac_rdp_keyboard* keyboard) {
free(keyboard);
guac_mem_free(keyboard);
}
int guac_rdp_keyboard_is_defined(guac_rdp_keyboard* keyboard, int keysym) {

Some files were not shown because too many files have changed in this diff Show More