diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2009-06-11 22:33:00 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2009-06-11 22:38:09 +0100 |
commit | 6167f27adfd530bdf091a0e7a3e0141d5db66f00 (patch) | |
tree | 9e202ab48fbed6da6b7d26880aaff797ae697368 /util | |
parent | 13b56c42bfdb9ad36f9b1bd22f83d7ef3a074ddc (diff) |
[script] Fix memleak of duplicated strings from files
csi_string_new() duplicated the bytes which was not what was desired, so
implement a csi_string_new_for_bytes() to take ownership and prevent the
leak that was occuring, for example, every time we create a new font face.
Diffstat (limited to 'util')
-rw-r--r-- | util/cairo-script/cairo-script-file.c | 5 | ||||
-rw-r--r-- | util/cairo-script/cairo-script-objects.c | 27 | ||||
-rw-r--r-- | util/cairo-script/cairo-script-private.h | 6 |
3 files changed, 36 insertions, 2 deletions
diff --git a/util/cairo-script/cairo-script-file.c b/util/cairo-script/cairo-script-file.c index 9a3ff70a3..a330d0bff 100644 --- a/util/cairo-script/cairo-script-file.c +++ b/util/cairo-script/cairo-script-file.c @@ -993,7 +993,7 @@ _csi_file_as_string (csi_t *ctx, break; len += ret; - if (len > allocated / 2) { + if (len + 1 > allocated / 2) { char *newbytes; int newlen; @@ -1011,7 +1011,8 @@ _csi_file_as_string (csi_t *ctx, } } while (TRUE); - status = csi_string_new (ctx, obj, bytes, len); + bytes[len] = '\0'; /* better safe than sorry! */ + status = csi_string_new_from_bytes (ctx, obj, bytes, len); if (status) { _csi_free (ctx, bytes); return status; diff --git a/util/cairo-script/cairo-script-objects.c b/util/cairo-script/cairo-script-objects.c index 204e4b8d8..4ff39ec52 100644 --- a/util/cairo-script/cairo-script-objects.c +++ b/util/cairo-script/cairo-script-objects.c @@ -559,6 +559,33 @@ csi_string_new (csi_t *ctx, return CSI_STATUS_SUCCESS; } +csi_status_t +csi_string_new_from_bytes (csi_t *ctx, + csi_object_t *obj, + char *bytes, + unsigned int len) +{ + csi_string_t *string; + + if (_csi_unlikely (len >= INT_MAX)) + return _csi_error (CSI_STATUS_NO_MEMORY); + + string = _csi_slab_alloc (ctx, sizeof (csi_string_t)); + if (_csi_unlikely (string == NULL)) + return _csi_error (CSI_STATUS_NO_MEMORY); + + string->string = bytes; + string->len = len; + + string->base.type = CSI_OBJECT_TYPE_STRING; + string->base.ref = 1; + + obj->type = CSI_OBJECT_TYPE_STRING; + obj->datum.string = string; + + return CSI_STATUS_SUCCESS; +} + static inline csi_status_t _csi_string_execute (csi_t *ctx, csi_string_t *string) { diff --git a/util/cairo-script/cairo-script-private.h b/util/cairo-script/cairo-script-private.h index d177a2985..d19737afa 100644 --- a/util/cairo-script/cairo-script-private.h +++ b/util/cairo-script/cairo-script-private.h @@ -737,6 +737,12 @@ csi_string_new (csi_t *ctx, const char *str, int len); +csi_private csi_status_t +csi_string_new_from_bytes (csi_t *ctx, + csi_object_t *obj, + char *bytes, + unsigned int len); + csi_private void csi_string_free (csi_t *ctx, csi_string_t *string); |