aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2021-03-08 00:21:02 +0100
committerMattias Andrée <maandree@kth.se>2021-03-08 00:21:02 +0100
commitb058098fdcc5d4ed9b81fdb17f64820c0360ad48 (patch)
treee39e5f547b900922775d466507c29b352f046a53
parentmisc (diff)
downloadlibgamma-b058098fdcc5d4ed9b81fdb17f64820c0360ad48.tar.gz
libgamma-b058098fdcc5d4ed9b81fdb17f64820c0360ad48.tar.bz2
libgamma-b058098fdcc5d4ed9b81fdb17f64820c0360ad48.tar.xz
m + style fix + check memory allocation overflows
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r--TODO2
-rw-r--r--fake-quartz-cg.c10
-rw-r--r--fake-w32-gdi.c16
-rw-r--r--legacy.c2
-rw-r--r--libgamma.h36
-rw-r--r--libgamma_behex_edid.c8
-rw-r--r--libgamma_behex_edid_lowercase.c4
-rw-r--r--libgamma_behex_edid_uppercase.c4
-rw-r--r--libgamma_connector_type_count.c6
-rw-r--r--libgamma_dummy_crtc_initialise.c33
-rw-r--r--libgamma_dummy_internal_crtc_restore_forced.c9
-rw-r--r--libgamma_dummy_partition_initialise.c6
-rw-r--r--libgamma_dummy_partition_restore.c2
-rw-r--r--libgamma_dummy_site_initialise.c4
-rw-r--r--libgamma_dummy_site_restore.c2
-rw-r--r--libgamma_gamma_ramps16_initialise.c8
-rw-r--r--libgamma_gamma_ramps32_initialise.c8
-rw-r--r--libgamma_gamma_ramps64_initialise.c8
-rw-r--r--libgamma_gamma_ramps8_initialise.c8
-rw-r--r--libgamma_gamma_rampsd_initialise.c8
-rw-r--r--libgamma_gamma_rampsf_initialise.c8
-rw-r--r--libgamma_internal_allocated_any_ramp.c24
-rw-r--r--libgamma_internal_parse_edid.c2
-rw-r--r--libgamma_internal_translate_to_64.c66
-rw-r--r--libgamma_internal_translated_ramp_get_.c17
-rw-r--r--libgamma_internal_translated_ramp_set_.c17
-rw-r--r--libgamma_linux_drm_crtc_initialise.c1
-rw-r--r--libgamma_linux_drm_crtc_set_gamma_ramps16.c1
-rw-r--r--libgamma_linux_drm_get_crtc_information.c23
-rw-r--r--libgamma_linux_drm_partition_initialise.c14
-rw-r--r--libgamma_linux_drm_site_initialise.c3
-rw-r--r--libgamma_list_methods.c2
-rw-r--r--libgamma_quartz_cg_crtc_get_gamma_rampsf.c4
-rw-r--r--libgamma_quartz_cg_partition_initialise.c16
-rw-r--r--libgamma_quartz_cg_site_initialise.c18
-rw-r--r--libgamma_value_of_connector_type.c21
-rw-r--r--libgamma_value_of_subpixel_order.c21
-rw-r--r--libgamma_w32_gdi_crtc_initialise.c1
-rw-r--r--libgamma_w32_gdi_get_crtc_information.c7
-rw-r--r--libgamma_w32_gdi_partition_initialise.c2
-rw-r--r--libgamma_x_randr_get_crtc_information.c31
-rw-r--r--libgamma_x_randr_method_capabilities.c2
-rw-r--r--libgamma_x_randr_partition_initialise.c31
-rw-r--r--libgamma_x_randr_site_initialise.c2
-rw-r--r--libgamma_x_vidmode_get_crtc_information.c2
-rw-r--r--test.c34
46 files changed, 365 insertions, 189 deletions
diff --git a/TODO b/TODO
index e8fcc7c..86f245e 100644
--- a/TODO
+++ b/TODO
@@ -8,3 +8,5 @@ Unsupported display servers:
Add hotplug support.
Generate librarian and pkg-config files.
+
+Replace use of atoi and atoll.
diff --git a/fake-quartz-cg.c b/fake-quartz-cg.c
index b0cc574..999609b 100644
--- a/fake-quartz-cg.c
+++ b/fake-quartz-cg.c
@@ -6,7 +6,8 @@
* It should by no means be used, without additional modification, as a
* part of a compatibility layer. The purpose of this file is only to make
* it possible to test for logical errors in Max OS X specific code on
- * a GNU/Linux system under X. */
+ * a Linux system under X.
+ */
@@ -217,7 +218,7 @@ CGGetOnlineDisplayList(uint32_t max_size, CGDirectDisplayID *restrict displays_o
}
/* Get the number of CRTC:s */
- crtc_count = (uint32_t)(res_reply->num_crtcs);
+ crtc_count = (uint32_t)res_reply->num_crtcs;
/* Get the CRTC ID:s */
crtcs = xcb_randr_get_screen_resources_current_crtcs(res_reply);
@@ -227,8 +228,13 @@ CGGetOnlineDisplayList(uint32_t max_size, CGDirectDisplayID *restrict displays_o
* `CGDisplayRestoreColorSyncSettings` which restore the
* all gamma ramps on the system to the system settnigs.
*/
+ if (crtc_count > SIZE_MAX / sizeof(*original_ramps) / 256 / 3) {
+ errno = ENOMEM;
+ goto original_ramps_malloc_fail;
+ }
original_ramps = malloc(crtc_count * 3 * 256 * sizeof(*original_ramps));
if (!original_ramps) {
+ original_ramps_malloc_fail:
perror("malloc");
xcb_disconnect(connection);
crtc_count = 0;
diff --git a/fake-w32-gdi.c b/fake-w32-gdi.c
index e5978a2..5e425f7 100644
--- a/fake-w32-gdi.c
+++ b/fake-w32-gdi.c
@@ -6,7 +6,8 @@
* It should by no means be used, without additional modification, as a
* part of a compatibility layer. The purpose of this file is only to make
* it possible to test for logical errors in Windows specific code on
- * a GNU/Linux system under X. */
+ * a Linux system under X.
+ */
@@ -291,11 +292,10 @@ SetDeviceGammaRamp(HDC hDC, LPVOID restrict lpRamp)
{
/* We assume that our gamma ramps are of the same size
* as used by Windows GDI (we are so sloppy) */
- xcb_void_cookie_t gamma_cookie =
- xcb_randr_set_crtc_gamma_checked(connection, *(xcb_randr_crtc_t *)hDC, GAMMA_RAMP_SIZE,
- &((uint16_t *)lpRamp)[0 * GAMMA_RAMP_SIZE],
- &((uint16_t *)lpRamp)[1 * GAMMA_RAMP_SIZE],
- &((uint16_t *)lpRamp)[2 * GAMMA_RAMP_SIZE]);
+ uint16_t *ramp = lpRamp;
+ xcb_void_cookie_t gamma_cookie = xcb_randr_set_crtc_gamma_checked(connection, *(xcb_randr_crtc_t *)hDC, GAMMA_RAMP_SIZE,
+ &ramp[0 * GAMMA_RAMP_SIZE], &ramp[1 * GAMMA_RAMP_SIZE],
+ &ramp[2 * GAMMA_RAMP_SIZE]);
xcb_generic_error_t *error = xcb_request_check(connection, gamma_cookie);
return !error ? TRUE : FALSE;
}
@@ -386,8 +386,8 @@ CreateDC(LPCTSTR restrict lpszDriver, LPCTSTR restrict lpszDevice, LPCTSTR restr
/* Was the index too high */
if (crtc_index >= crtc_count) {
/* Disconnect and release resouces and mark that
- we do not know the number of available CRTC:s
- if we have not opened any monitors yet */
+ * we do not know the number of available CRTC:s
+ * if we have not opened any monitors yet */
if (!dc_count) {
xcb_disconnect(connection);
free(res_reply);
diff --git a/legacy.c b/legacy.c
index 7e37ec3..550676d 100644
--- a/legacy.c
+++ b/legacy.c
@@ -62,7 +62,7 @@ libgamma_get_crtc_information(struct libgamma_crtc_information *restrict this,
struct libgamma_crtc_state *restrict crtc, int32_t fields)
{
return libgamma_get_crtc_information__new(this, offsetof(struct libgamma_crtc_information, gamma_error) +
- sizeof(this->gamma_error), crtc, (unsigned long long int)fields);
+ sizeof(this->gamma_error), crtc, (unsigned long long)fields);
}
int
diff --git a/libgamma.h b/libgamma.h
index c1afac6..b22f0d8 100644
--- a/libgamma.h
+++ b/libgamma.h
@@ -787,9 +787,9 @@ struct libgamma_method_capabilities {
*
* On operating systems that integrate a graphical environment
* there is usually just one site. However, one systems with
- * pluggable graphics, like Unix-like systems such as GNU/Linux
- * and the BSD:s, there can usually be any (feasible) number of
- * sites. In X.org parlance they are called displays.
+ * pluggable graphics, like Unix-like systems such as Linux
+ * and the BSD:s, there can usually be any (feasible) number
+ * of sites. In X.org parlance they are called displays.
*/
struct libgamma_site_state {
/**
@@ -1974,12 +1974,13 @@ const char *libgamma_const_of_connector_type(enum libgamma_connector_type);
*
* @param connector The name of the connector type, for example
* "VGA" or "LIBGAMMA_CONNECTOR_TYPE_VGA"
- * @return The connector type; for example `LIBGAMMA_CONNECTOR_TYPE_VGA`
- * for "VGA" and "LIBGAMMA_CONNECTOR_TYPE_VGA";
- * `LIBGAMMA_CONNECTOR_TYPE_NOT_RECOGNISED` of not defined
+ * @param out Output parameter for the connector type, only set on success;
+ * for example `LIBGAMMA_CONNECTOR_TYPE_VGA` for "VGA" and
+ * "LIBGAMMA_CONNECTOR_TYPE_VGA";
+ * @return Zero on success, `LIBGAMMA_CONNECTOR_TYPE_NOT_RECOGNISED` of not defined
*/
-LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__, __warn_unused_result__, __access__(__read_only__, 1), __pure__)))
-int libgamma_value_of_connector_type(const char *); /* FIXME return type */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__, __access__(__read_only__, 1), __access__(__write_only__, 2), __pure__)))
+int libgamma_value_of_connector_type(const char *, enum libgamma_connector_type *);
@@ -2014,12 +2015,13 @@ const char *libgamma_const_of_subpixel_order(enum libgamma_subpixel_order);
*
* @param order The name of the subpixel order, for example
* "Horizontal RGB" or "LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB"
- * @return The subpixel order; for example `LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB`
- * for "Horizontal RGB" and "LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB";
- * `LIBGAMMA_SUBPIXEL_ORDER_NOT_RECOGNISED` of not defined
+ * @param out Output parameter for the subpixel order, only set on success;
+ * for example `LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB` for
+ * "Horizontal RGB" and "LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB";
+ * @return Zero on success, `LIBGAMMA_SUBPIXEL_ORDER_NOT_RECOGNISED` of not defined
*/
-LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__, __warn_unused_result__, __access__(__read_only__, 1), __pure__)))
-int libgamma_value_of_subpixel_order(const char *); /* FIXME return type */
+LIBGAMMA_GCC_ONLY__(__attribute__((__nonnull__, __access__(__read_only__, 1), __access__(__write_only__, 2), __pure__)))
+int libgamma_value_of_subpixel_order(const char *, enum libgamma_subpixel_order *);
@@ -2496,10 +2498,10 @@ char *libgamma_behex_edid_uppercase(const unsigned char *restrict, size_t);
/**
* Convert a raw representation of an EDID to a lowercase hexadecimal representation
*
- * @param edid:const unsigned char* The EDID in raw representation
- * @param length:size_t The length of `edid`
- * @return :char* The EDID in lowercase hexadecimal representation,
- * `NULL` on allocation error, `errno` will be set accordingly
+ * @param edid The EDID in raw representation
+ * @param length The length of `edid`
+ * @return The EDID in lowercase hexadecimal representation,
+ * `NULL` on allocation error, `errno` will be set accordingly
*/
LIBGAMMA_GCC_ONLY__(__attribute__((__warn_unused_result__, __access__(__read_only__, 1, 2))))
inline char *
diff --git a/libgamma_behex_edid.c b/libgamma_behex_edid.c
index 269d68f..f4dea30 100644
--- a/libgamma_behex_edid.c
+++ b/libgamma_behex_edid.c
@@ -5,9 +5,9 @@
/**
* Convert a raw representation of an EDID to a lowercase hexadecimal representation
*
- * @param edid:const unsigned char* The EDID in raw representation
- * @param length:size_t The length of `edid`
- * @return :char* The EDID in lowercase hexadecimal representation,
- * `NULL` on allocation error, `errno` will be set accordingly
+ * @param edid The EDID in raw representation
+ * @param length The length of `edid`
+ * @return The EDID in lowercase hexadecimal representation,
+ * `NULL` on allocation error, `errno` will be set accordingly
*/
extern inline char *libgamma_behex_edid(const unsigned char *restrict, size_t);
diff --git a/libgamma_behex_edid_lowercase.c b/libgamma_behex_edid_lowercase.c
index 9c4f04e..41a2563 100644
--- a/libgamma_behex_edid_lowercase.c
+++ b/libgamma_behex_edid_lowercase.c
@@ -17,6 +17,10 @@ libgamma_behex_edid_lowercase(const unsigned char *restrict edid, size_t length)
size_t i;
/* Allocate memory area for the output string */
+ if (length > (SIZE_MAX / sizeof(char) - 1) / 2) {
+ errno = ENOMEM;
+ return NULL;
+ }
out = malloc((length * 2 + 1) * sizeof(char));
if (!out)
return NULL;
diff --git a/libgamma_behex_edid_uppercase.c b/libgamma_behex_edid_uppercase.c
index 5545aa5..4b25987 100644
--- a/libgamma_behex_edid_uppercase.c
+++ b/libgamma_behex_edid_uppercase.c
@@ -17,6 +17,10 @@ libgamma_behex_edid_uppercase(const unsigned char *restrict edid, size_t length)
size_t i;
/* Allocate memory area for the output string */
+ if (length > (SIZE_MAX / sizeof(char) - 1) / 2) {
+ errno = ENOMEM;
+ return NULL;
+ }
out = malloc((length * 2 + 1) * sizeof(char));
if (!out)
return NULL;
diff --git a/libgamma_connector_type_count.c b/libgamma_connector_type_count.c
index dfd38ec..646fd70 100644
--- a/libgamma_connector_type_count.c
+++ b/libgamma_connector_type_count.c
@@ -2,8 +2,12 @@
#include "common.h"
+#define X(...) +1
+
/**
* The number of values defined in `libgamma_connector_type_t`
* in the version of the library the program is linked against
*/
-const int libgamma_connector_type_count = LIBGAMMA_CONNECTOR_TYPE_COUNT;
+const int libgamma_connector_type_count = LIST_CONNECTOR_TYPES(X);
+
+#undef X
diff --git a/libgamma_dummy_crtc_initialise.c b/libgamma_dummy_crtc_initialise.c
index a3f9c87..7b36b86 100644
--- a/libgamma_dummy_crtc_initialise.c
+++ b/libgamma_dummy_crtc_initialise.c
@@ -35,15 +35,32 @@ libgamma_dummy_crtc_initialise(struct libgamma_crtc_state *restrict this,
else
stop_size = (size_t)data->info.gamma_depth / 8;
- data->gamma_red = malloc(data->info.red_gamma_size * stop_size);
- if (!data->gamma_red)
- goto fail;
- data->gamma_green = malloc(data->info.green_gamma_size * stop_size);
- if (!data->gamma_green)
- goto fail;
- data->gamma_blue = malloc(data->info.blue_gamma_size * stop_size);
- if (!data->gamma_blue)
+ data->gamma_red = NULL;
+ data->gamma_green = NULL;
+ data->gamma_blue = NULL;
+
+ if (data->info.red_gamma_size > SIZE_MAX / stop_size ||
+ data->info.green_gamma_size > SIZE_MAX / stop_size ||
+ data->info.blue_gamma_size > SIZE_MAX / stop_size) {
+ errno = ENOMEM;
goto fail;
+ }
+
+ if (data->info.red_gamma_size) {
+ data->gamma_red = malloc(data->info.red_gamma_size * stop_size);
+ if (!data->gamma_red)
+ goto fail;
+ }
+ if (data->info.green_gamma_size) {
+ data->gamma_green = malloc(data->info.green_gamma_size * stop_size);
+ if (!data->gamma_green)
+ goto fail;
+ }
+ if (data->info.blue_gamma_size) {
+ data->gamma_blue = malloc(data->info.blue_gamma_size * stop_size);
+ if (!data->gamma_blue)
+ goto fail;
+ }
return libgamma_dummy_internal_crtc_restore_forced(data);
diff --git a/libgamma_dummy_internal_crtc_restore_forced.c b/libgamma_dummy_internal_crtc_restore_forced.c
index a3c460f..fd23e72 100644
--- a/libgamma_dummy_internal_crtc_restore_forced.c
+++ b/libgamma_dummy_internal_crtc_restore_forced.c
@@ -17,6 +17,9 @@ libgamma_dummy_internal_crtc_restore_forced(struct libgamma_dummy_crtc *restrict
size_t rn = data->info. red_gamma_size;
size_t gn = data->info.green_gamma_size;
size_t bn = data->info. blue_gamma_size;
+ double rm = (double)(rn - 1);
+ double gm = (double)(gn - 1);
+ double bm = (double)(bn - 1);
size_t i;
if (!data->gamma_red)
@@ -27,9 +30,9 @@ libgamma_dummy_internal_crtc_restore_forced(struct libgamma_dummy_crtc *restrict
TYPE *red = data->gamma_red;\
TYPE *green = data->gamma_green;\
TYPE *blue = data->gamma_blue;\
- for (i = 0; i < rn; i++) red [i] = (TYPE)((double)(MAX) * ((double)i / (double)(rn - 1)));\
- for (i = 0; i < gn; i++) green[i] = (TYPE)((double)(MAX) * ((double)i / (double)(gn - 1)));\
- for (i = 0; i < bn; i++) blue [i] = (TYPE)((double)(MAX) * ((double)i / (double)(bn - 1)));\
+ for (i = 0; i < rn; i++) red [i] = (TYPE)((double)(MAX) * ((double)i / rm));\
+ for (i = 0; i < gn; i++) green[i] = (TYPE)((double)(MAX) * ((double)i / gm));\
+ for (i = 0; i < bn; i++) blue [i] = (TYPE)((double)(MAX) * ((double)i / bm));\
} while (0)
if (data->info.gamma_depth == 8) RESET_RAMPS(uint8_t, INT8_MAX);
diff --git a/libgamma_dummy_partition_initialise.c b/libgamma_dummy_partition_initialise.c
index 2557413..e8f3834 100644
--- a/libgamma_dummy_partition_initialise.c
+++ b/libgamma_dummy_partition_initialise.c
@@ -45,11 +45,11 @@ libgamma_dummy_partition_initialise(struct libgamma_partition_state *restrict th
memcpy(crtc_data->info.edid, template.edid, crtc_data->info.edid_length * sizeof(char));
}
if (crtc_data->info.connector_name) {
- n = strlen(crtc_data->info.connector_name);
- crtc_data->info.connector_name = malloc((n + 1) * sizeof(char));
+ n = strlen(crtc_data->info.connector_name) + 1;
+ crtc_data->info.connector_name = malloc(n * sizeof(char));
if (!crtc_data->info.connector_name)
goto fail;
- memcpy(crtc_data->info.connector_name, template.connector_name, (n + 1) * sizeof(char));
+ memcpy(crtc_data->info.connector_name, template.connector_name, n * sizeof(char));
}
}
diff --git a/libgamma_dummy_partition_restore.c b/libgamma_dummy_partition_restore.c
index b7fc4ac..fc393ee 100644
--- a/libgamma_dummy_partition_restore.c
+++ b/libgamma_dummy_partition_restore.c
@@ -22,7 +22,7 @@ libgamma_dummy_partition_restore(struct libgamma_partition_state *restrict this)
}
for (i = 0; i < data->crtc_count; i++)
- if (libgamma_dummy_internal_crtc_restore_forced(data->crtcs + i) < 0)
+ if (libgamma_dummy_internal_crtc_restore_forced(data->crtcs + i))
return -1;
return 0;
diff --git a/libgamma_dummy_site_initialise.c b/libgamma_dummy_site_initialise.c
index 1eb617e..ae79ccc 100644
--- a/libgamma_dummy_site_initialise.c
+++ b/libgamma_dummy_site_initialise.c
@@ -45,6 +45,10 @@ libgamma_dummy_site_initialise(struct libgamma_site_state *restrict this, char *
if (!libgamma_dummy_internal_configurations.capabilities.multiple_crtcs)
crtcs = !!crtcs;
+ if (data->partition_count * sizeof(*data->partitions)) {
+ errno = ENOMEM;
+ goto fail;
+ }
data->partitions = malloc(data->partition_count * sizeof(*data->partitions));
if (!data->partitions)
goto fail;
diff --git a/libgamma_dummy_site_restore.c b/libgamma_dummy_site_restore.c
index 0e8a7a5..97db77c 100644
--- a/libgamma_dummy_site_restore.c
+++ b/libgamma_dummy_site_restore.c
@@ -23,7 +23,7 @@ libgamma_dummy_site_restore(struct libgamma_site_state *restrict this)
for (j = 0; j < data->partition_count; j++)
for (i = 0; i < data->partitions[j].crtc_count; i++)
- if (libgamma_dummy_internal_crtc_restore_forced(data->partitions[j].crtcs + i) < 0)
+ if (libgamma_dummy_internal_crtc_restore_forced(data->partitions[j].crtcs + i))
return -1;
return 0;
diff --git a/libgamma_gamma_ramps16_initialise.c b/libgamma_gamma_ramps16_initialise.c
index 08d242b..63823fd 100644
--- a/libgamma_gamma_ramps16_initialise.c
+++ b/libgamma_gamma_ramps16_initialise.c
@@ -16,6 +16,14 @@ int
libgamma_gamma_ramps16_initialise(struct libgamma_gamma_ramps16 *restrict this)
{
size_t n = this->red_size + this->green_size + this->blue_size;
+ if (!n) {
+ this->red = this->green = this->blue = NULL;
+ return 0;
+ }
+ if (n > SIZE_MAX / sizeof(*this->red)) {
+ errno = ENOMEM;
+ return -1;
+ }
#ifdef HAVE_LIBGAMMA_METHOD_LINUX_DRM
/* Valgrind complains about us reading uninitialize memory if we just use malloc */
this->red = calloc(n, sizeof(*this->red));
diff --git a/libgamma_gamma_ramps32_initialise.c b/libgamma_gamma_ramps32_initialise.c
index 1134c8d..dc1006a 100644
--- a/libgamma_gamma_ramps32_initialise.c
+++ b/libgamma_gamma_ramps32_initialise.c
@@ -16,6 +16,14 @@ int
libgamma_gamma_ramps32_initialise(struct libgamma_gamma_ramps32 *restrict this)
{
size_t n = this->red_size + this->green_size + this->blue_size;
+ if (!n) {
+ this->red = this->green = this->blue = NULL;
+ return 0;
+ }
+ if (n > SIZE_MAX / sizeof(*this->red)) {
+ errno = ENOMEM;
+ return -1;
+ }
this->red = malloc(n * sizeof(*this->red));
this->green = &this-> red[this-> red_size];
this->blue = &this->green[this->green_size];
diff --git a/libgamma_gamma_ramps64_initialise.c b/libgamma_gamma_ramps64_initialise.c
index 9580028..1fa9962 100644
--- a/libgamma_gamma_ramps64_initialise.c
+++ b/libgamma_gamma_ramps64_initialise.c
@@ -16,6 +16,14 @@ int
libgamma_gamma_ramps64_initialise(struct libgamma_gamma_ramps64 *restrict this)
{
size_t n = this->red_size + this->green_size + this->blue_size;
+ if (!n) {
+ this->red = this->green = this->blue = NULL;
+ return 0;
+ }
+ if (n > SIZE_MAX / sizeof(*this->red)) {
+ errno = ENOMEM;
+ return -1;
+ }
this->red = malloc(n * sizeof(*this->red));
this->green = &this-> red[this-> red_size];
this->blue = &this->green[this->green_size];
diff --git a/libgamma_gamma_ramps8_initialise.c b/libgamma_gamma_ramps8_initialise.c
index 04bf465..6434707 100644
--- a/libgamma_gamma_ramps8_initialise.c
+++ b/libgamma_gamma_ramps8_initialise.c
@@ -16,6 +16,14 @@ int
libgamma_gamma_ramps8_initialise(struct libgamma_gamma_ramps8 *restrict this)
{
size_t n = this->red_size + this->green_size + this->blue_size;
+ if (!n) {
+ this->red = this->green = this->blue = NULL;
+ return 0;
+ }
+ if (n > SIZE_MAX / sizeof(*this->red)) {
+ errno = ENOMEM;
+ return -1;
+ }
this->red = malloc(n * sizeof(*this->red));
this->green = &this-> red[this-> red_size];
this->blue = &this->green[this->green_size];
diff --git a/libgamma_gamma_rampsd_initialise.c b/libgamma_gamma_rampsd_initialise.c
index f3ca3ef..df7cee2 100644
--- a/libgamma_gamma_rampsd_initialise.c
+++ b/libgamma_gamma_rampsd_initialise.c
@@ -16,6 +16,14 @@ int
libgamma_gamma_rampsd_initialise(struct libgamma_gamma_rampsd *restrict this)
{
size_t n = this->red_size + this->green_size + this->blue_size;
+ if (!n) {
+ this->red = this->green = this->blue = NULL;
+ return 0;
+ }
+ if (n > SIZE_MAX / sizeof(*this->red)) {
+ errno = ENOMEM;
+ return -1;
+ }
this->red = malloc(n * sizeof(*this->red));
this->green = &this-> red[this-> red_size];
this->blue = &this->green[this->green_size];
diff --git a/libgamma_gamma_rampsf_initialise.c b/libgamma_gamma_rampsf_initialise.c
index 0937bc7..5cd9290 100644
--- a/libgamma_gamma_rampsf_initialise.c
+++ b/libgamma_gamma_rampsf_initialise.c
@@ -16,6 +16,14 @@ int
libgamma_gamma_rampsf_initialise(struct libgamma_gamma_rampsf *restrict this)
{
size_t n = this->red_size + this->green_size + this->blue_size;
+ if (!n) {
+ this->red = this->green = this->blue = NULL;
+ return 0;
+ }
+ if (n > SIZE_MAX / sizeof(*this->red)) {
+ errno = ENOMEM;
+ return -1;
+ }
this->red = malloc(n * sizeof(*this->red));
this->green = &this-> red[this-> red_size];
this->blue = &this->green[this->green_size];
diff --git a/libgamma_internal_allocated_any_ramp.c b/libgamma_internal_allocated_any_ramp.c
index afb128c..c9dbe3e 100644
--- a/libgamma_internal_allocated_any_ramp.c
+++ b/libgamma_internal_allocated_any_ramp.c
@@ -24,7 +24,17 @@ libgamma_internal_allocated_any_ramp(union gamma_ramps_any *restrict ramps_sys,
signed depth, size_t *restrict elements)
{
/* Calculate the size of the allocation to do */
- size_t d, n = ramps->ANY.red_size + ramps->ANY.green_size + ramps->ANY.blue_size;
+ size_t d, n = ramps->ANY.red_size;
+ if (n > SIZE_MAX - ramps->ANY.green_size) {
+ goto enomem;
+ }
+ n += ramps->ANY.green_size;
+ if (n > SIZE_MAX - ramps->ANY.blue_size) {
+ enomem:
+ errno = ENOMEM;
+ return LIBGAMMA_ERRNO_SET;
+ }
+ n += ramps->ANY.blue_size;
switch (depth) {
case 8: d = sizeof(uint8_t); break;
case 16: d = sizeof(uint16_t); break;
@@ -33,16 +43,26 @@ libgamma_internal_allocated_any_ramp(union gamma_ramps_any *restrict ramps_sys,
case -1: d = sizeof(float); break;
case -2: d = sizeof(double); break;
default:
- return errno = EINVAL, LIBGAMMA_ERRNO_SET;
+ errno = EINVAL;
+ return LIBGAMMA_ERRNO_SET;
}
/* Copy the gamma ramp sizes */
ramps_sys->ANY = ramps->ANY;
/* Allocate the new ramps */
+ if (!n) {
+ ramps_sys->ANY.red = NULL;
+ ramps_sys->ANY.green = NULL;
+ ramps_sys->ANY.blue = NULL;
+ *elements = n;
+ return 0;
+ }
#ifdef HAVE_LIBGAMMA_METHOD_LINUX_DRM
/* Valgrind complains about us reading uninitialize memory if we just use malloc */
ramps_sys->ANY.red = calloc(n, d);
#else
+ if (n > SIZE_MAX / d)
+ goto enomem;
ramps_sys->ANY.red = malloc(n * d);
#endif
ramps_sys->ANY.green = (void *)&((char *)ramps_sys->ANY. red)[ramps->ANY. red_size * d / sizeof(char)];
diff --git a/libgamma_internal_parse_edid.c b/libgamma_internal_parse_edid.c
index 9c8a84f..05d34a8 100644
--- a/libgamma_internal_parse_edid.c
+++ b/libgamma_internal_parse_edid.c
@@ -84,7 +84,7 @@ libgamma_internal_parse_edid(struct libgamma_crtc_information *restrict this, un
blue_x = (uint16_t)((((uint16_t)this->edid[26] >> 6) & 2) | ((uint16_t)this->edid[31] << 2));
blue_y = (uint16_t)((((uint16_t)this->edid[26] >> 4) & 2) | ((uint16_t)this->edid[32] << 2));
white_x = (uint16_t)((((uint16_t)this->edid[26] >> 2) & 2) | ((uint16_t)this->edid[33] << 2));
- white_y = (uint16_t)((((uint16_t)this->edid[26] >> 6) & 2) | ((uint16_t)this->edid[34] << 2));
+ white_y = (uint16_t)((((uint16_t)this->edid[26] >> 0) & 2) | ((uint16_t)this->edid[34] << 2));
/* Even though the maximum value as encoded is 1023, the values should be divided by 1024 */
this->red_chroma_x = (float)red_x / 1024.f;
this->red_chroma_y = (float)red_y / 1024.f;
diff --git a/libgamma_internal_translate_to_64.c b/libgamma_internal_translate_to_64.c
index 24cb0ed..5452fa2 100644
--- a/libgamma_internal_translate_to_64.c
+++ b/libgamma_internal_translate_to_64.c
@@ -30,17 +30,17 @@ float_to_64(float value)
#if defined(HAVE_INT128) && __WORDSIZE == 64
/* `__int128` is a GNU C extension, which
- (because it is not ISO C) emits a warning
- under -pedantic */
+ * (because it is not ISO C) emits a warning
+ * under -pedantic */
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wpedantic"
/* In GCC we can use `__int128`, this is
- a signed 128-bit integer. It fits all
- uint64_t values but also native values,
- which is a nice because it eleminates
- some overflow condition tests. It is
- also more readable. */
+ * a signed 128-bit integer. It fits all
+ * uint64_t values but also native values,
+ * which is a nice because it eleminates
+ * some overflow condition tests. It is
+ * also more readable. */
/* Convert to integer */
__int128 product = (__int128)(value * (float)UINT64_MAX);
@@ -57,22 +57,22 @@ float_to_64(float value)
#else
/* If we are not using GCC we cannot be
- sure that we have `__int128` so we have
- to use `uint64_t` and perform overflow
- checkes based on the input value */
+ * sure that we have `__int128` so we have
+ * to use `uint64_t` and perform overflow
+ * checkes based on the input value */
/* Convert to integer. */
uint64_t product = (uint64_t)(value * (float)UINT64_MAX);
/* Negative overflow,
- if the input is less than 0.5 but
- the output is greater then we got
- -1 when we should have gotten 0 */
+ * if the input is less than 0.5 but
+ * the output is greater then we got
+ * -1 when we should have gotten 0 */
if (value < 0.1f && product > 0xF000000000000000ULL)
return 0;
/* Positive overflow,
- if the input is greater than 0.5
- but the output is less then we got
- 0 when we should have gotten ~0 */
+ * if the input is greater than 0.5
+ * but the output is less then we got
+ * 0 when we should have gotten ~0 */
else if (value > 0.9f && product < 0x1000000000000000ULL)
return (uint64_t)~0;
/* Did not overflow */
@@ -97,17 +97,17 @@ double_to_64(double value)
#if defined(HAVE_INT128) && __WORDSIZE == 64
/* `__int128` is a GNU C extension, which
- (because it is not ISO C) emits a warning
- under -pedantic */
+ * (because it is not ISO C) emits a warning
+ * under -pedantic */
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wpedantic"
/* In GCC we can use `__int128`, this is
- a signed 128-bit integer. It fits all
- uint64_t values but also native values,
- which is a nice because it eleminates
- some overflow condition tests. It is
- also more readable. */
+ * a signed 128-bit integer. It fits all
+ * uint64_t values but also native values,
+ * which is a nice because it eleminates
+ * some overflow condition tests. It is
+ * also more readable. */
/* Convert to integer */
__int128 product = (__int128)(value * (double)UINT64_MAX);
@@ -124,23 +124,23 @@ double_to_64(double value)
#else
/* If we are not using GCC we cannot be
- sure that we have `__int128` so we have
- to use `uint64_t` and perform overflow
- checkes based on the input value. */
+ * sure that we have `__int128` so we have
+ * to use `uint64_t` and perform overflow
+ * checkes based on the input value. */
/* Convert to integer. */
uint64_t product = (uint64_t)(value * (double)UINT64_MAX);
/* Negative overflow,
- if the input is less than 0.5 but
- the output is greater then we got
- -1 when we should have gotten 0 */
+ * if the input is less than 0.5 but
+ * the output is greater then we got
+ * -1 when we should have gotten 0 */
if (value < (double)0.1f && product > 0xF000000000000000ULL)
product = 0;
/* Positive overflow,
- if the input is greater than 0.5
- but the output is less then we got
- 0 when we should have gotten ~0 */
- else if ((value > (double)0.9f) && (product < 0x1000000000000000ULL))
+ * if the input is greater than 0.5
+ * but the output is less then we got
+ * 0 when we should have gotten ~0 */
+ else if (value > (double)0.9f && (product < 0x1000000000000000ULL))
product = (uint64_t)~0;
/* Did not overflow */
return product;
diff --git a/libgamma_internal_translated_ramp_get_.c b/libgamma_internal_translated_ramp_get_.c
index 852f6c9..c5f563e 100644
--- a/libgamma_internal_translated_ramp_get_.c
+++ b/libgamma_internal_translated_ramp_get_.c
@@ -30,7 +30,7 @@ libgamma_internal_translated_ramp_get_(struct libgamma_crtc_state *restrict this
size_t n;
int r;
union gamma_ramps_any ramps_sys;
- uint64_t *restrict ramps_full;
+ uint64_t *restrict ramps_full = NULL;
/* Allocate ramps with proper data type */
if ((r = libgamma_internal_allocated_any_ramp(&ramps_sys, ramps, depth_system, &n)))
@@ -43,10 +43,17 @@ libgamma_internal_translated_ramp_get_(struct libgamma_crtc_state *restrict this
}
/* Allocate intermediary ramps */
- ramps_full = malloc(n * sizeof(*ramps_full));
- if (!ramps_full) {
- free(ramps_sys.ANY.red);
- return LIBGAMMA_ERRNO_SET;
+ if (n) {
+ if (n > SIZE_MAX / sizeof(*ramps_full)) {
+ errno = ENOMEM;
+ free(ramps_sys.ANY.red);
+ return LIBGAMMA_ERRNO_SET;
+ }
+ ramps_full = malloc(n * sizeof(*ramps_full));
+ if (!ramps_full) {
+ free(ramps_sys.ANY.red);
+ return LIBGAMMA_ERRNO_SET;
+ }
}
/* Translate ramps to 64-bit integers */
diff --git a/libgamma_internal_translated_ramp_set_.c b/libgamma_internal_translated_ramp_set_.c
index f249e54..359193c 100644
--- a/libgamma_internal_translated_ramp_set_.c
+++ b/libgamma_internal_translated_ramp_set_.c
@@ -30,17 +30,24 @@ libgamma_internal_translated_ramp_set_(struct libgamma_crtc_state *restrict this
size_t n;
int r;
union gamma_ramps_any ramps_sys;
- uint64_t *restrict ramps_full;
+ uint64_t *restrict ramps_full = NULL;
/* Allocate ramps with proper data type */
if ((r = libgamma_internal_allocated_any_ramp(&ramps_sys, ramps, depth_system, &n)))
return r;
/* Allocate intermediary ramps */
- ramps_full = malloc(n * sizeof(*ramps_full));
- if (!ramps_full) {
- free(ramps_sys.ANY.red);
- return LIBGAMMA_ERRNO_SET;
+ if (n) {
+ if (n > SIZE_MAX / sizeof(*ramps_full)) {
+ errno = ENOMEM;
+ free(ramps_sys.ANY.red);
+ return LIBGAMMA_ERRNO_SET;
+ }
+ ramps_full = malloc(n * sizeof(*ramps_full));
+ if (!ramps_full) {
+ free(ramps_sys.ANY.red);
+ return LIBGAMMA_ERRNO_SET;
+ }
}
/* Translate ramps to 64-bit integers. */
diff --git a/libgamma_linux_drm_crtc_initialise.c b/libgamma_linux_drm_crtc_initialise.c
index e047ad6..a9320ad 100644
--- a/libgamma_linux_drm_crtc_initialise.c
+++ b/libgamma_linux_drm_crtc_initialise.c
@@ -17,7 +17,6 @@ libgamma_linux_drm_crtc_initialise(struct libgamma_crtc_state *restrict this,
struct libgamma_partition_state *restrict partition, size_t crtc)
{
struct libgamma_drm_card_data *restrict card = partition->data;
-
if (crtc >= partition->crtcs_available)
return LIBGAMMA_NO_SUCH_CRTC;
this->data = (void *)(size_t)card->res->crtcs[crtc];
diff --git a/libgamma_linux_drm_crtc_set_gamma_ramps16.c b/libgamma_linux_drm_crtc_set_gamma_ramps16.c
index a150029..3d0c983 100644
--- a/libgamma_linux_drm_crtc_set_gamma_ramps16.c
+++ b/libgamma_linux_drm_crtc_set_gamma_ramps16.c
@@ -17,6 +17,7 @@ libgamma_linux_drm_crtc_set_gamma_ramps16(struct libgamma_crtc_state *restrict t
{
struct libgamma_drm_card_data *restrict card = this->partition->data;
int r;
+
#ifdef DEBUG
/* Gamma ramp sizes are identical but not fixed */
if (ramps->red_size != ramps->green_size || ramps->red_size != ramps->blue_size)
diff --git a/libgamma_linux_drm_get_crtc_information.c b/libgamma_linux_drm_get_crtc_information.c
index a476878..683fa0e 100644
--- a/libgamma_linux_drm_get_crtc_information.c
+++ b/libgamma_linux_drm_get_crtc_information.c
@@ -20,7 +20,7 @@ find_connector(struct libgamma_crtc_state *restrict this, int *restrict error)
/* Open connectors and encoders if not already opened */
if (!card->connectors) {
/* Allocate connector and encoder arrays; we use `calloc`
- so all non-loaded elements are `NULL` after an error */
+ * so all non-loaded elements are `NULL` after an error */
card->connectors = calloc(n, sizeof(drmModeConnector *));
if (!card->connectors)
goto fail;
@@ -34,8 +34,8 @@ find_connector(struct libgamma_crtc_state *restrict this, int *restrict error)
if (!card->connectors[i])
goto fail;
/* Get encoder if the connector is enabled. If it is disabled it
- will not have an encoder, which is indicated by the encoder
- ID being 0. In such case, leave the encoder to be `NULL`. */
+ * will not have an encoder, which is indicated by the encoder
+ * ID being 0. In such case, leave the encoder to be `NULL`. */
if (card->connectors[i]->encoder_id) {
card->encoders[i] = drmModeGetEncoder(card->fd, card->connectors[i]->encoder_id);
if (!card->encoders[i])
@@ -55,7 +55,7 @@ find_connector(struct libgamma_crtc_state *restrict this, int *restrict error)
fail:
/* Report the error that got us here, release
- resouces and exit with `NULL` for failure */
+ * resouces and exit with `NULL` for failure */
*error = errno;
libgamma_linux_drm_internal_release_connectors_and_encoders(card);
return NULL;
@@ -194,7 +194,7 @@ read_connector_data(struct libgamma_crtc_state *restrict crtc, struct libgamma_c
const char *connector_name_base = NULL;
struct libgamma_drm_card_data *restrict card;
uint32_t type;
- size_t i, n, c;
+ size_t i, n, c, len;
/* Get some information that does not require too much work */
if (fields & (LIBGAMMA_CRTC_INFO_MACRO_ACTIVE | LIBGAMMA_CRTC_INFO_MACRO_CONNECTOR)) {
@@ -227,9 +227,16 @@ read_connector_data(struct libgamma_crtc_state *restrict crtc, struct libgamma_c
n = (size_t)card->res->count_connectors;
/* Allocate memory for the name of the connector */
- out->connector_name = malloc((strlen(connector_name_base) + 12) * sizeof(char));
- if (!out->connector_name)
+ len = strlen(connector_name_base);
+ if (len > SIZE_MAX / sizeof(char) - 12) {
+ errno = ENOMEM;
+ out->connector_name = NULL;
return (out->connector_name_error = errno);
+ } else {
+ out->connector_name = malloc((len + 12) * sizeof(char));
+ if (!out->connector_name)
+ return (out->connector_name_error = errno);
+ }
/* Get the number of connectors with the same type on the same graphics card */
for (i = c = 0; i < n && card->connectors[i] != connector; i++)
@@ -285,7 +292,7 @@ get_edid(struct libgamma_crtc_state *restrict crtc, struct libgamma_crtc_informa
out->edid_error = errno;
} else {
/* Copy the EDID so we can free resources that got us here */
- memcpy(out->edid, blob->data, (size_t)out->edid_length * sizeof(char));
+ memcpy(out->edid, blob->data, (size_t)out->edid_length * sizeof(unsigned char));
}
/* Free the propriety value and the propery */
drmModeFreePropertyBlob(blob);
diff --git a/libgamma_linux_drm_partition_initialise.c b/libgamma_linux_drm_partition_initialise.c
index 8136cd9..5440365 100644
--- a/libgamma_linux_drm_partition_initialise.c
+++ b/libgamma_linux_drm_partition_initialise.c
@@ -32,7 +32,7 @@ figure_out_card_open_error(const char *pathname)
return LIBGAMMA_ERRNO_SET;
}
- /* TODO Can this be simplified? */
+ /* TODO Can this be simplified? Is this even correct? */
#define TEST(R, W) ((attr.st_mode & ((R) | (W))) == ((R) | (W)))
/* Get permission requirement for the file */
@@ -45,7 +45,7 @@ figure_out_card_open_error(const char *pathname)
return LIBGAMMA_DEVICE_ACCESS_FAILED;
/* The group should be "video", but perhaps
- it is "root" to restrict users */
+ * it is "root" to restrict users */
if (!attr.st_gid /* root group */ || TEST(S_IRGRP, S_IWGRP))
return LIBGAMMA_DEVICE_RESTRICTED;
@@ -56,19 +56,19 @@ figure_out_card_open_error(const char *pathname)
return LIBGAMMA_ERRNO_SET;
/* Test whether any of the supplemental
- group should be satisfactory */
+ * group should be satisfactory */
for (i = 0; i < n; i++)
if (supplemental_groups[i] == attr.st_gid)
break;
/* If one of the supplemental groups should be satisfactory,
- then we do not know anything more than that access failed */
+ * then we do not know anything more than that access failed */
if (i != n)
return LIBGAMMA_DEVICE_ACCESS_FAILED;
/* Otherwise, try to get the name of the group that is
- required and report the missing group membership */
- errno = getgrgid_r(attr.st_gid, &_grp, buf, sizeof(buf) / sizeof(char), &group);
+ * required and report the missing group membership */
+ errno = getgrgid_r(attr.st_gid, &_grp, buf, sizeof(buf), &group);
if (errno == ERANGE) {
/* The lenght of the group's name is absurdly long, degrade to thread-unsafe. */
errno = 0;
@@ -118,7 +118,7 @@ libgamma_linux_drm_partition_initialise(struct libgamma_partition_state *restric
data->connectors = NULL;
/* Get the pathname for the graphics card */
- snprintf(pathname, sizeof(pathname) / sizeof(char), DRM_DEV_NAME, DRM_DIR_NAME, (int)partition);
+ snprintf(pathname, sizeof(pathname), DRM_DEV_NAME, DRM_DIR_NAME, (int)partition);
/* Acquire access to the graphics card */
data->fd = open(pathname, O_RDWR | O_CLOEXEC);
diff --git a/libgamma_linux_drm_site_initialise.c b/libgamma_linux_drm_site_initialise.c
index 9c57bd1..f6e4734 100644
--- a/libgamma_linux_drm_site_initialise.c
+++ b/libgamma_linux_drm_site_initialise.c
@@ -30,8 +30,7 @@ libgamma_linux_drm_site_initialise(struct libgamma_site_state *restrict this, ch
this->partitions_available = 0;
for (;;) {
/* Construct pathname of graphics card device */
- snprintf(pathname, sizeof(pathname) / sizeof(char),
- DRM_DEV_NAME, DRM_DIR_NAME, (int)(this->partitions_available));
+ snprintf(pathname, sizeof(pathname), DRM_DEV_NAME, DRM_DIR_NAME, (int)this->partitions_available);
/* `stat` the graphics card's existence */
if (stat(pathname, &_attr))
break;
diff --git a/libgamma_list_methods.c b/libgamma_list_methods.c
index 6da4f43..cca8426 100644
--- a/libgamma_list_methods.c
+++ b/libgamma_list_methods.c
@@ -14,7 +14,7 @@ is_vt_proper(int fd)
char buf[32], digit0;
/* Get TTY */
- if (ttyname_r(fd, buf, sizeof(buf) / sizeof(char)))
+ if (ttyname_r(fd, buf, sizeof(buf)))
return 0;
/* Validate TTY path */
diff --git a/libgamma_quartz_cg_crtc_get_gamma_rampsf.c b/libgamma_quartz_cg_crtc_get_gamma_rampsf.c
index 3f03437..b90524d 100644
--- a/libgamma_quartz_cg_crtc_get_gamma_rampsf.c
+++ b/libgamma_quartz_cg_crtc_get_gamma_rampsf.c
@@ -28,8 +28,8 @@ libgamma_quartz_cg_crtc_get_gamma_rampsf(struct libgamma_crtc_state *restrict th
if (r != kCGErrorSuccess)
return LIBGAMMA_GAMMA_RAMP_READ_FAILED;
/* I hope that it will not actually ever change,
- but it does return the the gamma ramp size despite
- that it can be queried without querying for more */
+ * but it does return the the gamma ramp size despite
+ * that it can be queried without querying for more */
if (gamma_size_out != ramps->red_size)
return LIBGAMMA_GAMMA_RAMP_SIZE_CHANGED;
return 0;
diff --git a/libgamma_quartz_cg_partition_initialise.c b/libgamma_quartz_cg_partition_initialise.c
index 80fb4fc..ff77ba0 100644
--- a/libgamma_quartz_cg_partition_initialise.c
+++ b/libgamma_quartz_cg_partition_initialise.c
@@ -36,16 +36,24 @@ libgamma_quartz_cg_partition_initialise(struct libgamma_partition_state *restric
* of CRTC:s and ask for more if we got as many as we asked for. */
for (;;) {
/* Ask for CRTC ID:s */
- if (CGGetOnlineDisplayList(cap, crtcs, &n) != kCGErrorSuccess)
- return free(crtcs), LIBGAMMA_LIST_CRTCS_FAILED;
+ if (CGGetOnlineDisplayList(cap, crtcs, &n) != kCGErrorSuccess) {
+ free(crtcs);
+ return LIBGAMMA_LIST_CRTCS_FAILED;
+ }
/* If we did not get as many as we asked for then we have all */
if (n < cap)
break;
/* Increase the number CRTC ID:s to ask for */
- if (cap > UINT32_MAX / 2) /* We could also test ~0, but it is still too many */
- return free(crtcs), LIBGAMMA_IMPOSSIBLE_AMOUNT;
+ if (cap > UINT32_MAX / 2) { /* We could also test ~0, but it is still too many */
+ free(crtcs);
+ return LIBGAMMA_IMPOSSIBLE_AMOUNT;
+ }
cap <<= 1;
/* Grow the array of CRTC ID:s so that it can fit all we are asking for */
+ if ((size_t)cap > SIZE_MAX / sizeof(CGDirectDisplayID)) {
+ errno = ENOMEM;
+ return LIBGAMMA_ERRNO_SET;
+ }
crtcs = realloc(crtcs_old = crtcs, (size_t)cap * sizeof(CGDirectDisplayID));
if (!crtcs) {
free(crtcs_old);
diff --git a/libgamma_quartz_cg_site_initialise.c b/libgamma_quartz_cg_site_initialise.c
index cc47e3a..c842629 100644
--- a/libgamma_quartz_cg_site_initialise.c
+++ b/libgamma_quartz_cg_site_initialise.c
@@ -6,15 +6,15 @@
/**
* Initialise an allocated site state
*
- * @param this The site state to initialise
- * @param site The site identifier, unless it is `NULL` it must a
- * `free`:able. Once the state is destroyed the library
- * will attempt to free it. There you should not free
- * it yourself, and it must not be a string constant
- * or allocate on the stack. Note however that it will
- * not be free:d if this function fails.
- * @return Zero on success, otherwise (negative) the value of an
- * error identifier provided by this library
+ * @param this The site state to initialise
+ * @param site The site identifier, unless it is `NULL` it must a
+ * `free`:able. Once the state is destroyed the library
+ * will attempt to free it. There you should not free
+ * it yourself, and it must not be a string constant
+ * or allocate on the stack. Note however that it will
+ * not be free:d if this function fails.
+ * @return Zero on success, otherwise (negative) the value of an
+ * error identifier provided by this library
*/
int
libgamma_quartz_cg_site_initialise(struct libgamma_site_state *restrict this, char *restrict site)
diff --git a/libgamma_value_of_connector_type.c b/libgamma_value_of_connector_type.c
index 249422e..395aed0 100644
--- a/libgamma_value_of_connector_type.c
+++ b/libgamma_value_of_connector_type.c
@@ -7,22 +7,27 @@
*
* @param connector The name of the connector type, for example
* "VGA" or "LIBGAMMA_CONNECTOR_TYPE_VGA"
- * @return The connector type; for example `LIBGAMMA_CONNECTOR_TYPE_VGA`
- * for "VGA" and "LIBGAMMA_CONNECTOR_TYPE_VGA";
- * `LIBGAMMA_CONNECTOR_TYPE_NOT_RECOGNISED` of not defined
+ * @param out Output parameter for the connector type, only set on success;
+ * for example `LIBGAMMA_CONNECTOR_TYPE_VGA` for "VGA" and
+ * "LIBGAMMA_CONNECTOR_TYPE_VGA";
+ * @return Zero on success, `LIBGAMMA_CONNECTOR_TYPE_NOT_RECOGNISED` of not defined
*/
int
-libgamma_value_of_connector_type(const char *connector)
+libgamma_value_of_connector_type(const char *connector, enum libgamma_connector_type *out)
{
#define X(CONST, NAME, ...)\
- if (!strcmp(connector, NAME))\
- return CONST;
+ if (!strcmp(connector, NAME)) {\
+ *out = CONST;\
+ return 0;\
+ }
LIST_CONNECTOR_TYPES(X)
#undef X
#define X(CONST, ...)\
- if (!strcmp(connector, #CONST))\
- return CONST;
+ if (!strcmp(connector, #CONST)) {\
+ *out = CONST;\
+ return 0;\
+ }
LIST_CONNECTOR_TYPES(X)
#undef X
diff --git a/libgamma_value_of_subpixel_order.c b/libgamma_value_of_subpixel_order.c
index 33c2a6f..ed81435 100644
--- a/libgamma_value_of_subpixel_order.c
+++ b/libgamma_value_of_subpixel_order.c
@@ -7,22 +7,27 @@
*
* @param order The name of the subpixel order, for example
* "Horizontal RGB" or "LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB"
- * @return The subpixel order; for example `LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB`
- * for "Horizontal RGB" and "LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB";
- * `LIBGAMMA_SUBPIXEL_ORDER_NOT_RECOGNISED` of not defined
+ * @param out Output parameter for the subpixel order, only set on success;
+ * for example `LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB` for
+ * "Horizontal RGB" and "LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB";
+ * @return Zero on success, `LIBGAMMA_SUBPIXEL_ORDER_NOT_RECOGNISED` of not defined
*/
int
-libgamma_value_of_subpixel_order(const char *order)
+libgamma_value_of_subpixel_order(const char *order, enum libgamma_subpixel_order *out)
{
#define X(CONST, NAME, ...)\
- if (!strcmp(order, NAME))\
- return CONST;
+ if (!strcmp(order, NAME)) {\
+ *out = CONST;\
+ return 0;\
+ }
LIST_SUBPIXEL_ORDERS(X)
#undef X
#define X(CONST, ...)\
- if (!strcmp(order, #CONST))\
- return CONST;
+ if (!strcmp(order, #CONST)) {\
+ *out = CONST;\
+ return 0;\
+ }
LIST_SUBPIXEL_ORDERS(X)
#undef X
diff --git a/libgamma_w32_gdi_crtc_initialise.c b/libgamma_w32_gdi_crtc_initialise.c
index 5b75e3a..20d83ac 100644
--- a/libgamma_w32_gdi_crtc_initialise.c
+++ b/libgamma_w32_gdi_crtc_initialise.c
@@ -3,7 +3,6 @@
#include "common.h"
-
/**
* Initialise an allocated CRTC state
*
diff --git a/libgamma_w32_gdi_get_crtc_information.c b/libgamma_w32_gdi_get_crtc_information.c
index 74c9d73..9e37122 100644
--- a/libgamma_w32_gdi_get_crtc_information.c
+++ b/libgamma_w32_gdi_get_crtc_information.c
@@ -3,7 +3,6 @@
#include "common.h"
-
/**
* Read information about a CRTC
*
@@ -36,9 +35,9 @@ libgamma_w32_gdi_get_crtc_information(struct libgamma_crtc_information *restrict
this->gamma_depth = 16;
this->gamma_depth_error = 0;
/* It is possible to query Windows GDI whether the device
- have gamma ramp support. It cannot fail. However, I think
- the result is incorrect if multiple monitors are active,
- so we cannot include this. */
+ * have gamma ramp support. It cannot fail. However, I think
+ * the result is incorrect if multiple monitors are active,
+ * so we cannot include this. */
/*
if ((fields & LIBGAMMA_CRTC_INFO_GAMMA_SUPPORT))
this->gamma_support = GetDeviceCaps(crtc->data, COLORMGMTCAPS) == CM_GAMMA_RAMP;
diff --git a/libgamma_w32_gdi_partition_initialise.c b/libgamma_w32_gdi_partition_initialise.c
index 1bd3f5c..8fe8741 100644
--- a/libgamma_w32_gdi_partition_initialise.c
+++ b/libgamma_w32_gdi_partition_initialise.c
@@ -26,7 +26,7 @@ libgamma_w32_gdi_partition_initialise(struct libgamma_partition_state *restrict
return LIBGAMMA_NO_SUCH_PARTITION;
/* Count CRTC:s by iteration over all possible identifiers
- until we reach on that does not exist */
+ * until we reach on that does not exist */
display.cb = sizeof(DISPLAY_DEVICE);
while (EnumDisplayDevices(NULL, n, &display, 0))
if (n++ == UINT32_MAX)
diff --git a/libgamma_x_randr_get_crtc_information.c b/libgamma_x_randr_get_crtc_information.c
index 8bf2e8f..75885e6 100644
--- a/libgamma_x_randr_get_crtc_information.c
+++ b/libgamma_x_randr_get_crtc_information.c
@@ -109,19 +109,19 @@ get_connector_type(struct libgamma_crtc_information *restrict this)
} while (0)
/* Check begin on the name of the output to find out what type the connector is of */
- SELECT ("None", Unknown);
- SELECT ("VGA", VGA);
- SELECT ("DVI-I", DVII);
- SELECT ("DVI-D", DVID);
- SELECT ("DVI-A", DVIA);
- SELECT ("DVI", DVI);
- SELECT ("Composite", Composite);
- SELECT ("S-Video", SVIDEO);
- SELECT ("Component", Component);
- SELECT ("LFP", LFP);
- SELECT ("Proprietary", Unknown);
- SELECT ("HDMI", HDMI);
- SELECT ("DisplayPort", DisplayPort);
+ SELECT("None", Unknown);
+ SELECT("VGA", VGA);
+ SELECT("DVI-I", DVII);
+ SELECT("DVI-D", DVID);
+ SELECT("DVI-A", DVIA);
+ SELECT("DVI", DVI);
+ SELECT("Composite", Composite);
+ SELECT("S-Video", SVIDEO);
+ SELECT("Component", Component);
+ SELECT("LFP", LFP);
+ SELECT("Proprietary", Unknown);
+ SELECT("HDMI", HDMI);
+ SELECT("DisplayPort", DisplayPort);
#undef SELECT
@@ -153,6 +153,11 @@ get_output_name(struct libgamma_crtc_information *restrict out, xcb_randr_get_ou
return out->connector_name_error = LIBGAMMA_REPLY_VALUE_EXTRACTION_FAILED;
/* Allocate a memory area for a NUL-terminated copy of the name */
+ if (length > SIZE_MAX / sizeof(char) - 1) {
+ out->connector_name = NULL;
+ out->connector_name_error = errno = ENOMEM;
+ return -1;
+ }
store = out->connector_name = malloc(((size_t)length + 1) * sizeof(char));
if (!store) {
out->connector_name_error = errno;
diff --git a/libgamma_x_randr_method_capabilities.c b/libgamma_x_randr_method_capabilities.c
index 17e9b0e..7ce1c0b 100644
--- a/libgamma_x_randr_method_capabilities.c
+++ b/libgamma_x_randr_method_capabilities.c
@@ -13,7 +13,7 @@ libgamma_x_randr_method_capabilities(struct libgamma_method_capabilities *restri
{
char *display = getenv("DISPLAY");
/* Support for all information except active status and gamma ramp support.
- Active status can be queried but it is not guaranteed produces an up to date result. */
+ * Active status can be queried but it is not guaranteed produces an up to date result. */
this->crtc_information = LIBGAMMA_CRTC_INFO_MACRO_EDID
| LIBGAMMA_CRTC_INFO_MACRO_VIEWPORT
| LIBGAMMA_CRTC_INFO_MACRO_RAMP
diff --git a/libgamma_x_randr_partition_initialise.c b/libgamma_x_randr_partition_initialise.c
index fae2442..5c88eb6 100644
--- a/libgamma_x_randr_partition_initialise.c
+++ b/libgamma_x_randr_partition_initialise.c
@@ -7,13 +7,20 @@
* Duplicate a memory area
*
* @param ptr The memory area
- * @param bytes The size, in bytes, of the memory area
+ * @param nelem The number of elements in the memory area
+ * @param size The size, in bytes, of each element
* @return A duplication of the memory, `NULL` if zero-length or on error
*/
static inline void *
-xmemdup(void *restrict ptr, size_t bytes)
+duparray(void *restrict ptr, size_t nelem, size_t size)
{
char *restrict rc;
+ size_t bytes;
+ if (nelem > SIZE_MAX / size) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ bytes = nelem * size;
if (!bytes)
return NULL;
rc = malloc(bytes);
@@ -91,18 +98,18 @@ libgamma_x_randr_partition_initialise(struct libgamma_partition_state *restrict
}
/* Allocate adjustment method dependent data memory area.
- We use `calloc` because we want `data`'s pointers to be `NULL` if not allocated at `fail`. */
+ * We use `calloc` because we want `data`'s pointers to be `NULL` if not allocated at `fail`. */
data = calloc(1, sizeof(*data));
if (!data)
goto fail;
/* Copy the CRTC:s, just so we do not have to keep the reply in memory */
- data->crtcs = xmemdup(crtcs, (size_t)reply->num_crtcs * sizeof(*crtcs));
+ data->crtcs = duparray(crtcs, (size_t)reply->num_crtcs, sizeof(*crtcs));
if (!data->crtcs && reply->num_crtcs > 0)
goto fail;
/* Copy the outputs as well */
- data->outputs = xmemdup(outputs, (size_t)reply->num_outputs * sizeof(*outputs));
+ data->outputs = duparray(outputs, (size_t)reply->num_outputs, sizeof(*outputs));
if (!data->outputs && reply->num_outputs > 0)
goto fail;
@@ -110,11 +117,17 @@ libgamma_x_randr_partition_initialise(struct libgamma_partition_state *restrict
data->outputs_count = (size_t)reply->num_outputs;
/* Create mapping table from CRTC indices to output indicies. (injection) */
- data->crtc_to_output = malloc((size_t)reply->num_crtcs * sizeof(*data->crtc_to_output));
- if (!data->crtc_to_output)
- goto fail;
+ if (reply->num_crtcs) {
+ if (reply->num_crtcs > SIZE_MAX / sizeof(*data->crtc_to_output)) {
+ errno = ENOMEM;
+ goto fail;
+ }
+ data->crtc_to_output = malloc((size_t)reply->num_crtcs * sizeof(*data->crtc_to_output));
+ if (!data->crtc_to_output)
+ goto fail;
+ }
/* All CRTC:s should be mapped, but incase they are not, all unmapped CRTC:s should have
- an invalid target, namely `SIZE_MAX`, which is 1 more than the theoretical limit */
+ * an invalid target, namely `SIZE_MAX`, which is 1 more than the theoretical limit */
for (i = 0; i < (size_t)reply->num_crtcs; i++)
data->crtc_to_output[i] = SIZE_MAX;
/* Fill the table */
diff --git a/libgamma_x_randr_site_initialise.c b/libgamma_x_randr_site_initialise.c
index f582748..5e2b776 100644
--- a/libgamma_x_randr_site_initialise.c
+++ b/libgamma_x_randr_site_initialise.c
@@ -51,7 +51,7 @@ libgamma_x_randr_site_initialise(struct libgamma_site_state *restrict this, char
}
/* Check protocol compatibility,
- we require 1.3 but 2.x may not be backwards compatible */
+ * we require 1.3 but 2.x may not be backwards compatible */
if (reply->major_version != RANDR_VERSION_MAJOR || reply->minor_version < RANDR_VERSION_MINOR) {
#ifdef DEBUG
/* Print used protocol */
diff --git a/libgamma_x_vidmode_get_crtc_information.c b/libgamma_x_vidmode_get_crtc_information.c
index 24d35c2..f014f41 100644
--- a/libgamma_x_vidmode_get_crtc_information.c
+++ b/libgamma_x_vidmode_get_crtc_information.c
@@ -28,7 +28,7 @@ libgamma_x_vidmode_get_crtc_information(struct libgamma_crtc_information *restri
this->height_mm_edid_error = _E(LIBGAMMA_CRTC_INFO_HEIGHT_MM_EDID);
this->gamma_size_error = 0;
/* X VidMode does support gamma ramp size query. The gamma
- ramps are identical but not fixed, and the query can fail. */
+ * ramps are identical but not fixed, and the query can fail. */
if ((fields & LIBGAMMA_CRTC_INFO_GAMMA_SIZE)) {
connection = crtc->partition->site->data;
if (!XF86VidModeGetGammaRampSize(connection, (int)crtc->partition->partition, &stops))
diff --git a/test.c b/test.c
index c00c5bc..2fbc897 100644
--- a/test.c
+++ b/test.c
@@ -335,7 +335,7 @@ select_monitor(struct libgamma_site_state *site_state, struct libgamma_partition
printf(" %i: %s\n", method, method_name(method));
printf("> ");
fflush(stdout);
- fgets(buf, sizeof(buf) / sizeof(char), stdin);
+ fgets(buf, sizeof(buf), stdin);
method = atoi(buf);
@@ -344,7 +344,7 @@ select_monitor(struct libgamma_site_state *site_state, struct libgamma_partition
/* Let the user select site */
printf("Select site: ");
fflush(stdout);
- fgets(buf, sizeof(buf) / sizeof(char), stdin);
+ fgets(buf, sizeof(buf), stdin);
tmp = strchr(buf, '\n');
if (tmp)
*tmp = '\0';
@@ -375,7 +375,7 @@ select_monitor(struct libgamma_site_state *site_state, struct libgamma_partition
/* Let the user select partition */
printf("Select partition [0, %lu]: ", site_state->partitions_available - 1);
fflush(stdout);
- fgets(buf, sizeof(buf) / sizeof(char), stdin);
+ fgets(buf, sizeof(buf), stdin);
/* Initialise partition state */
if ((r = libgamma_partition_initialise(part_state, site_state, (size_t)atoll(buf)))) {
@@ -398,7 +398,7 @@ select_monitor(struct libgamma_site_state *site_state, struct libgamma_partition
/* Let the user select CRTC */
printf("Select CRTC [0, %lu]: ", part_state->crtcs_available - 1);
fflush(stdout);
- fgets(buf, sizeof(buf) / sizeof(char), stdin);
+ fgets(buf, sizeof(buf), stdin);
/* Initialise CRTC state. */
if ((r = libgamma_crtc_initialise(crtc_state, part_state, (size_t)atoll(buf)))) {
@@ -431,7 +431,7 @@ select_monitor(struct libgamma_site_state *site_state, struct libgamma_partition
char buf[256];\
if (do_print) {\
if (error) {\
- snprintf(buf, sizeof(buf) / sizeof(char), " (error) %s", description);\
+ snprintf(buf, sizeof(buf), " (error) %s", description);\
libgamma_perror(buf, error);\
} else {\
printf(" %s: %" notation "\n", description, value);\
@@ -666,6 +666,7 @@ test_connector_types(void)
size_t n = 0;
char buf[128], *w;
const char *r;
+ enum libgamma_connector_type type;
#define X(CONST)\
do {\
@@ -685,16 +686,19 @@ test_connector_types(void)
fprintf(stderr, "libgamma_const_of_connector_type(%s) != \"%s\"\n", #CONST, #CONST);\
exit(1);\
}\
- if (libgamma_value_of_connector_type(#CONST) != CONST) {\
+ type = (enum libgamma_connector_type)-1;\
+ if (libgamma_value_of_connector_type(#CONST, &type) || type != CONST) { \
fprintf(stderr, "libgamma_value_of_connector_type(\"%s\") != %s\n", #CONST, #CONST);\
exit(1);\
}\
- if (libgamma_value_of_connector_type(libgamma_name_of_connector_type(CONST)) != CONST) {\
+ type = (enum libgamma_connector_type)-1;\
+ if (libgamma_value_of_connector_type(libgamma_name_of_connector_type(CONST), &type) || type != CONST) { \
fprintf(stderr, "libgamma_value_of_connector_type(libgamma_name_of_connector_type(%s)) != %s\n",\
#CONST, #CONST);\
exit(1);\
}\
- if (libgamma_value_of_connector_type(#CONST) != CONST) {\
+ type = (enum libgamma_connector_type)-1;\
+ if (libgamma_value_of_connector_type(#CONST, &type) || type != CONST) { \
fprintf(stderr, "libgamma_value_of_connector_type(\"%s\") != %s\n", #CONST, #CONST);\
exit(1);\
}\
@@ -754,7 +758,7 @@ test_connector_types(void)
fprintf(stderr, "libgamma_const_of_connector_type(<invalid>) != NULL\n");
exit(1);
}
- if (libgamma_value_of_connector_type("") != LIBGAMMA_CONNECTOR_TYPE_NOT_RECOGNISED) {
+ if (libgamma_value_of_connector_type("", &type) != LIBGAMMA_CONNECTOR_TYPE_NOT_RECOGNISED) {
fprintf(stderr, "libgamma_value_of_connector_type(<invalid>) != LIBGAMMA_CONNECTOR_TYPE_NOT_RECOGNISED\n");
exit(1);
}
@@ -770,6 +774,7 @@ test_subpixel_orders(void)
size_t n = 0;
char buf[128], *w;
const char *r;
+ enum libgamma_subpixel_order order;
#define X(CONST)\
do {\
@@ -789,16 +794,19 @@ test_subpixel_orders(void)
fprintf(stderr, "libgamma_const_of_subpixel_order(%s) != \"%s\"\n", #CONST, #CONST);\
exit(1);\
}\
- if (libgamma_value_of_subpixel_order(#CONST) != CONST) {\
+ order = (enum libgamma_subpixel_order)-1;\
+ if (libgamma_value_of_subpixel_order(#CONST, &order) || order != CONST) { \
fprintf(stderr, "libgamma_value_of_subpixel_order(\"%s\") != %s\n", #CONST, #CONST);\
exit(1);\
}\
- if (libgamma_value_of_subpixel_order(libgamma_name_of_subpixel_order(CONST)) != CONST) {\
+ order = (enum libgamma_subpixel_order)-1;\
+ if (libgamma_value_of_subpixel_order(libgamma_name_of_subpixel_order(CONST), &order) || order != CONST) { \
fprintf(stderr, "libgamma_value_of_subpixel_order(libgamma_name_of_subpixel_order(%s)) != %s\n",\
#CONST, #CONST);\
exit(1);\
}\
- if (libgamma_value_of_subpixel_order(#CONST) != CONST) {\
+ order = (enum libgamma_subpixel_order)-1;\
+ if (libgamma_value_of_subpixel_order(#CONST, &order) || order != CONST) { \
fprintf(stderr, "libgamma_value_of_subpixel_order(\"%s\") != %s\n", #CONST, #CONST);\
exit(1);\
}\
@@ -840,7 +848,7 @@ test_subpixel_orders(void)
fprintf(stderr, "libgamma_const_of_subpixel_order(<invalid>) != NULL\n");
exit(1);
}
- if (libgamma_value_of_subpixel_order("") != LIBGAMMA_SUBPIXEL_ORDER_NOT_RECOGNISED) {
+ if (libgamma_value_of_subpixel_order("", &order) != LIBGAMMA_SUBPIXEL_ORDER_NOT_RECOGNISED) {
fprintf(stderr, "libgamma_value_of_subpixel_order(<invalid>) != LIBGAMMA_SUBPIXEL_ORDER_NOT_RECOGNISED\n");
exit(1);
}