summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2012-02-10 23:55:24 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2012-02-10 23:55:24 (GMT)
commitc910863e19f9c9cc3db56924634315a37ecfe2bb (patch)
tree50bfed10a7859a141c470f598ee83cd31ca8ebfd
parentd0aa23eb9005cbc9b4e706ab70b5082be80bad35 (diff)
downloadtk-c910863e19f9c9cc3db56924634315a37ecfe2bb.zip
tk-c910863e19f9c9cc3db56924634315a37ecfe2bb.tar.gz
tk-c910863e19f9c9cc3db56924634315a37ecfe2bb.tar.bz2
proposed fix for bug-3486474
-rw-r--r--doc/GetColor.35
-rw-r--r--generic/tkColor.c55
-rw-r--r--generic/tkCursor.c4
-rw-r--r--generic/tkImgBmap.c4
-rw-r--r--generic/tkImgPhoto.c2
-rw-r--r--generic/tkInt.h7
-rw-r--r--mac/tkMacColor.c2
-rw-r--r--macosx/tkMacOSXColor.c2
-rw-r--r--unix/tkUnixColor.c2
-rw-r--r--unix/tkUnixCursor.c10
-rw-r--r--win/tkWinColor.c2
-rw-r--r--xlib/xcolors.c81
12 files changed, 143 insertions, 33 deletions
diff --git a/doc/GetColor.3 b/doc/GetColor.3
index 201edab..abd1620 100644
--- a/doc/GetColor.3
+++ b/doc/GetColor.3
@@ -95,8 +95,9 @@ to use to display the color. Each \fIR\fR, \fIG\fR, or \fIB\fR
represents a single hexadecimal digit. The four forms permit
colors to be specified with 4-bit, 8-bit, 12-bit or 16-bit values.
When fewer than 16 bits are provided for each color, they represent
-the most significant bits of the color. For example, #3a7 is the
-same as #3000a0007000.
+the most significant bits of the color, while the lower unfilled
+bits will be repeatedly replicated from the available higher bits.
+For example, #3a7 is the same as #3333aaaa7777.
.PP
.VS 8.1
\fBTk_AllocColorFromObj\fR returns a pointer to
diff --git a/generic/tkColor.c b/generic/tkColor.c
index f06c43f..87f3209 100644
--- a/generic/tkColor.c
+++ b/generic/tkColor.c
@@ -809,3 +809,58 @@ TkDebugColor(tkwin, name)
}
return resultPtr;
}
+
+#ifndef __WIN32__
+/* This function is not necessary for Win32,
+ * since XParseColor already does the right thing */
+Status
+TkParseColor(display, map, spec, colorPtr)
+ Display * display; /* The display */
+ Colormap map; /* Color map */
+ _Xconst char* spec; /* String to be parsed */
+ XColor * colorPtr;
+{
+ if (*spec == '#') {
+ char buf[14];
+ buf[0] = '#'; buf[13] = '\0';
+ if (!spec[1] || !spec[2] || !spec[3]) {
+ /* Not at least 3 hex digits, so invalid */
+ return 0;
+ } else if (!spec[4]) {
+ /* Exactly 3 hex digits */
+ buf[1] = buf[2] = buf[3] = buf[4] = spec[1];
+ buf[5] = buf[6] = buf[7] = buf[8] = spec[2];
+ buf[9] = buf[10] = buf[11] = buf[12] = spec[3];
+ return XParseColor(display, map, buf, colorPtr);
+ } else if (!spec[5] || !spec[6]) {
+ /* Not at least 6 hex digits, so invalid */
+ return 0;
+ } else if (!spec[7]) {
+ /* Exactly 6 hex digits */
+ buf[1] = buf[3] = spec[1];
+ buf[2] = buf[4] = spec[2];
+ buf[5] = buf[7] = spec[3];
+ buf[6] = buf[8] = spec[4];
+ buf[9] = buf[11] = spec[5];
+ buf[10] = buf[12] = spec[6];
+ return XParseColor(display, map, buf, colorPtr);
+ } else if (!spec[8] || !spec[9]) {
+ /* Not at least 9 hex digits, so invalid */
+ return 0;
+ } else if (!spec[10]) {
+ /* Exactly 9 hex digits */
+ buf[1] = buf[4] = spec[1];
+ buf[2] = spec[2];
+ buf[3] = spec[3];
+ buf[5] = buf[8] = spec[4];
+ buf[6] = spec[5];
+ buf[7] = spec[6];
+ buf[9] = buf[12] = spec[7];
+ buf[10] = spec[8];
+ buf[11] = spec[9];
+ return XParseColor(display, map, buf, colorPtr);
+ }
+ }
+ return XParseColor(display, map, spec, colorPtr);
+}
+#endif /* __WIN32__ */
diff --git a/generic/tkCursor.c b/generic/tkCursor.c
index 466d0ef..f599083 100644
--- a/generic/tkCursor.c
+++ b/generic/tkCursor.c
@@ -357,12 +357,12 @@ Tk_GetCursorFromData(interp, tkwin, source, mask, width, height,
* available and add it to the database.
*/
- if (XParseColor(dataKey.display, Tk_Colormap(tkwin), fg, &fgColor) == 0) {
+ if (TkParseColor(dataKey.display, Tk_Colormap(tkwin), fg, &fgColor) == 0) {
Tcl_AppendResult(interp, "invalid color name \"", fg, "\"",
(char *) NULL);
goto error;
}
- if (XParseColor(dataKey.display, Tk_Colormap(tkwin), bg, &bgColor) == 0) {
+ if (TkParseColor(dataKey.display, Tk_Colormap(tkwin), bg, &bgColor) == 0) {
Tcl_AppendResult(interp, "invalid color name \"", bg, "\"",
(char *) NULL);
goto error;
diff --git a/generic/tkImgBmap.c b/generic/tkImgBmap.c
index 99ae050..e1ccecb 100644
--- a/generic/tkImgBmap.c
+++ b/generic/tkImgBmap.c
@@ -1266,7 +1266,7 @@ ImgBmapPostscript(clientData, interp, tkwin, psinfo, x, y, width, height,
*/
if ((masterPtr->bgUid != NULL) && (masterPtr->bgUid[0] != '\000')) {
XColor color;
- XParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), masterPtr->bgUid,
+ TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), masterPtr->bgUid,
&color);
if (Tk_PostscriptColor(interp, psinfo, &color) != TCL_OK) {
return TCL_ERROR;
@@ -1286,7 +1286,7 @@ ImgBmapPostscript(clientData, interp, tkwin, psinfo, x, y, width, height,
*/
if ( (masterPtr->fgUid != NULL) && (masterPtr->data != NULL) ) {
XColor color;
- XParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), masterPtr->fgUid,
+ TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), masterPtr->fgUid,
&color);
if (Tk_PostscriptColor(interp, psinfo, &color) != TCL_OK) {
return TCL_ERROR;
diff --git a/generic/tkImgPhoto.c b/generic/tkImgPhoto.c
index 80b44d7..ffbb47c 100644
--- a/generic/tkImgPhoto.c
+++ b/generic/tkImgPhoto.c
@@ -1150,7 +1150,7 @@ ImgPhotoCmd(clientData, interp, objc, objv)
break;
}
for (x = 0; x < dataWidth; ++x) {
- if (!XParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin),
+ if (!TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin),
listArgv[x], &color)) {
Tcl_AppendResult(interp, "can't parse color \"",
listArgv[x], "\"", (char *) NULL);
diff --git a/generic/tkInt.h b/generic/tkInt.h
index 777201e..c274236 100644
--- a/generic/tkInt.h
+++ b/generic/tkInt.h
@@ -1213,6 +1213,13 @@ EXTERN int TkParsePadAmount _ANSI_ARGS_((Tcl_Interp *interp,
Tk_Window tkwin, Tcl_Obj *objPtr,
int *pad1Ptr, int *pad2Ptr));
EXTERN int TkpAlwaysShowSelection _ANSI_ARGS_((Tk_Window tkwin));
+#ifdef __WIN32__
+#define TkParseColor XParseColor
+#else
+EXTERN Status TkParseColor _ANSI_ARGS_((Display * display,
+ Colormap map, _Xconst char* spec,
+ XColor * colorPtr));
+#endif
/*
* Unsupported commands.
diff --git a/mac/tkMacColor.c b/mac/tkMacColor.c
index 6fd0263..6c3c230 100644
--- a/mac/tkMacColor.c
+++ b/mac/tkMacColor.c
@@ -274,7 +274,7 @@ TkpGetColor(
}
}
- if (XParseColor(display, colormap, name, &color) == 0) {
+ if (TkParseColor(display, colormap, name, &color) == 0) {
return (TkColor *) NULL;
}
diff --git a/macosx/tkMacOSXColor.c b/macosx/tkMacOSXColor.c
index 6ddb95e..9520a77 100644
--- a/macosx/tkMacOSXColor.c
+++ b/macosx/tkMacOSXColor.c
@@ -591,7 +591,7 @@ TkpGetColor(
}
}
- if (XParseColor(display, colormap, name, &color) == 0) {
+ if (TkParseColor(display, colormap, name, &color) == 0) {
return (TkColor *) NULL;
}
diff --git a/unix/tkUnixColor.c b/unix/tkUnixColor.c
index d001be5..aebbbca 100644
--- a/unix/tkUnixColor.c
+++ b/unix/tkUnixColor.c
@@ -168,7 +168,7 @@ TkpGetColor(tkwin, name)
FindClosestColor(tkwin, &screen, &color);
}
} else {
- if (XParseColor(display, colormap, buf, &color) == 0) {
+ if (TkParseColor(display, colormap, buf, &color) == 0) {
return (TkColor *) NULL;
}
if (XAllocColor(display, colormap, &color) != 0) {
diff --git a/unix/tkUnixCursor.c b/unix/tkUnixCursor.c
index 70e8b93..a4ee0cb 100644
--- a/unix/tkUnixCursor.c
+++ b/unix/tkUnixCursor.c
@@ -194,7 +194,7 @@ TkGetCursorByName(interp, tkwin, string)
fg.red = fg.green = fg.blue = 0;
bg.red = bg.green = bg.blue = 65535;
} else {
- if (XParseColor(display, Tk_Colormap(tkwin), argv[1],
+ if (TkParseColor(display, Tk_Colormap(tkwin), argv[1],
&fg) == 0) {
Tcl_AppendResult(interp, "invalid color name \"", argv[1],
"\"", (char *) NULL);
@@ -204,7 +204,7 @@ TkGetCursorByName(interp, tkwin, string)
bg.red = bg.green = bg.blue = 0;
maskIndex = namePtr->shape;
} else {
- if (XParseColor(display, Tk_Colormap(tkwin), argv[2],
+ if (TkParseColor(display, Tk_Colormap(tkwin), argv[2],
&bg) == 0) {
Tcl_AppendResult(interp, "invalid color name \"", argv[2],
"\"", (char *) NULL);
@@ -262,7 +262,7 @@ TkGetCursorByName(interp, tkwin, string)
goto cleanup;
}
if (argc == 2) {
- if (XParseColor(display, Tk_Colormap(tkwin), argv[1],
+ if (TkParseColor(display, Tk_Colormap(tkwin), argv[1],
&fg) == 0) {
Tcl_AppendResult(interp, "invalid color name \"",
argv[1], "\"", (char *) NULL);
@@ -285,13 +285,13 @@ TkGetCursorByName(interp, tkwin, string)
TCL_STATIC);
goto cleanup;
}
- if (XParseColor(display, Tk_Colormap(tkwin), argv[2],
+ if (TkParseColor(display, Tk_Colormap(tkwin), argv[2],
&fg) == 0) {
Tcl_AppendResult(interp, "invalid color name \"", argv[2],
"\"", (char *) NULL);
goto cleanup;
}
- if (XParseColor(display, Tk_Colormap(tkwin), argv[3],
+ if (TkParseColor(display, Tk_Colormap(tkwin), argv[3],
&bg) == 0) {
Tcl_AppendResult(interp, "invalid color name \"", argv[3],
"\"", (char *) NULL);
diff --git a/win/tkWinColor.c b/win/tkWinColor.c
index d3b3cad..088c216 100644
--- a/win/tkWinColor.c
+++ b/win/tkWinColor.c
@@ -201,7 +201,7 @@ TkpGetColor(tkwin, name)
if (((strncasecmp(name, "system", 6) == 0)
&& FindSystemColor(name+6, &color, &index))
- || XParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), name,
+ || TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), name,
&color)) {
winColPtr = (WinColor *) ckalloc(sizeof(WinColor));
winColPtr->info.color = color;
diff --git a/xlib/xcolors.c b/xlib/xcolors.c
index 32c53bd..598f27b 100644
--- a/xlib/xcolors.c
+++ b/xlib/xcolors.c
@@ -882,24 +882,71 @@ XParseColor(display, map, spec, colorPtr)
XColor *colorPtr;
{
if (spec[0] == '#') {
- char fmt[16];
- int i, red, green, blue;
+ char rstr[5], gstr[5], bstr[5];
- if ((i = (int) strlen(spec+1))%3) {
- return 0;
- }
- i /= 3;
-
- sprintf(fmt, "%%%dx%%%dx%%%dx", i, i, i);
- if (sscanf(spec+1, fmt, &red, &green, &blue) != 3) {
- return 0;
- }
- colorPtr->red = (((unsigned short) red) << (4 * (4 - i)))
- | ((unsigned short) red);
- colorPtr->green = (((unsigned short) green) << (4 * (4 - i)))
- | ((unsigned short) green);
- colorPtr->blue = (((unsigned short) blue) << (4 * (4 - i)))
- | ((unsigned short) blue);
+ if (!isxdigit((unsigned char) spec[1])
+ || !isxdigit((unsigned char) spec[2])
+ || !isxdigit((unsigned char) spec[3])) {
+ /* Not at least 3 hex digits, so invalid */
+ return 0;
+ } else if (!spec[4]) {
+ /* Exactly 3 hex digits */
+ rstr[0] = rstr[1] = rstr[2] = rstr[3] = spec[1];
+ gstr[0] = gstr[1] = gstr[2] = gstr[3] = spec[2];
+ bstr[0] = bstr[1] = bstr[2] = bstr[3] = spec[3];
+ } else if (!isxdigit((unsigned char) spec[4])
+ || !isxdigit((unsigned char) spec[5])
+ || !isxdigit((unsigned char) spec[6])) {
+ /* Not at least 6 hex digits, so invalid */
+ return 0;
+ } else if (!spec[7]) {
+ /* Exactly 6 hex digits */
+ rstr[0] = rstr[2] = spec[1];
+ rstr[1] = rstr[3] = spec[2];
+ gstr[0] = gstr[2] = spec[3];
+ gstr[1] = gstr[3] = spec[4];
+ bstr[0] = bstr[2] = spec[5];
+ bstr[1] = bstr[3] = spec[6];
+ } else if (!isxdigit((unsigned char) spec[7])
+ || !isxdigit((unsigned char) spec[8])
+ || !isxdigit((unsigned char) spec[9])) {
+ /* Not at least 9 hex digits, so invalid */
+ return 0;
+ } else if (!spec[10]) {
+ /* Exactly 9 hex digits */
+ rstr[0] = rstr[3] = spec[1];
+ rstr[1] = spec[2];
+ rstr[2] = spec[3];
+ gstr[0] = gstr[3] = spec[4];
+ gstr[1] = spec[5];
+ gstr[2] = spec[6];
+ bstr[0] = bstr[3] = spec[7];
+ bstr[1] = spec[8];
+ bstr[2] = spec[9];
+ } else if (!isxdigit((unsigned char) spec[10])
+ || !isxdigit((unsigned char) spec[11])
+ || !isxdigit((unsigned char) spec[12]) || spec[13]) {
+ /* Not exactly 12 hex digits, so invalid */
+ return 0;
+ } else {
+ /* Exactly 12 hex digits */
+ rstr[0] = spec[1];
+ rstr[1] = spec[2];
+ rstr[2] = spec[3];
+ rstr[3] = spec[4];
+ gstr[0] = spec[5];
+ gstr[1] = spec[6];
+ gstr[2] = spec[7];
+ gstr[3] = spec[8];
+ bstr[0] = spec[9];
+ bstr[1] = spec[10];
+ bstr[2] = spec[11];
+ bstr[3] = spec[12];
+ }
+ rstr[4] = gstr[4] = bstr[4] = '\0';
+ colorPtr->red = strtol(rstr, NULL, 16);
+ colorPtr->green = strtol(gstr, NULL, 16);
+ colorPtr->blue = strtol(bstr, NULL, 16);
} else {
if (!FindColor(spec, colorPtr)) {
return 0;