[argyllcms] [PATCH] Argyll segfaults with 256 byte EDID

  • From: Omari Stephens <xsdg@xxxxxxxxxxxxx>
  • To: argyllcms@xxxxxxxxxxxxx
  • Date: Mon, 29 Jun 2009 13:24:25 +0000

I upgraded a bunch of X-related stuff (including libraries), and now dispwin sefaults on start. I tracked the issue down to this:


(gdb) frame
#0  get_a_display (ix=0) at spectro/dispwin.c:994
994                     if ((rv->edid = malloc(sizeof(unsigned char) * 128)) == 
NULL) {
(gdb) p (*paths[i]).edid_len
$55 = 256

As expected, changing the 128 to 256 on lines 994 and 3242 fixes the problem. Doing a recursive grep for '[(]unsigned char[)] \* 128' suggests that these are the only instances of this specific problem.

dispwin.h seems to suggest that this should be supported, so I presume these lines should have been changed at some point in the past but weren't; maybe this value should be in a constant somewhere?

/* Structure to store infomation about possible displays */
typedef struct {
…
    unsigned char *edid;    /* 128 or 256 bytes of monitor EDID, NULL if none */
    int edid_len;           /* 128 or 256 */
…
} disppath

--xsdg

--- Argyll_V1.0.3/spectro/dispwin.c.orig        2009-06-29 13:20:20.664753092 
+0000
+++ Argyll_V1.0.3/spectro/dispwin.c     2009-06-29 13:14:34.906501084 +0000
@@ -991,7 +991,7 @@
        }
 #if defined(UNIX) && !defined(__APPLE__)
        if (paths[i]->edid != NULL) {
-               if ((rv->edid = malloc(sizeof(unsigned char) * 128)) == NULL) {
+               if ((rv->edid = malloc(sizeof(unsigned char) * 256)) == NULL) {
                        debugrr("get_displays failed on malloc\n");
                        free(rv);
                        free_disppaths(paths);
@@ -3239,7 +3239,7 @@
 #endif /* randr >= V 1.2 */
 
                if (disp->edid != NULL) {
-                       if ((p->edid = malloc(sizeof(unsigned char) * 128)) == 
NULL) {
+                       if ((p->edid = malloc(sizeof(unsigned char) * 256)) == 
NULL) {
                                debugr2((errout,"Malloc failed\n"));
                                dispwin_del(p);
                                return NULL;

Other related posts: