aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathias Gumz <akira at fluxbox dot org>2008-09-23 07:13:53 (GMT)
committerMathias Gumz <akira at fluxbox dot org>2008-09-23 07:13:53 (GMT)
commitacd690ff653d83e4a24f88445526449d345f81bd (patch)
tree2f74d3faa688ed3f70213f0487ac2bbf237e21db
parent769ca8f1c8e156d919f6cacf90e0651530c4d943 (diff)
downloadfluxbox_paul-acd690ff653d83e4a24f88445526449d345f81bd.zip
fluxbox_paul-acd690ff653d83e4a24f88445526449d345f81bd.tar.bz2
fixed detection of bad values in the _NET_WM_ICON property. eg, tvtime.sf.net
is not aware of how to correctly feed icon data into the property on 64bit architecture which caused the dimensions of the icon beeing corrupt and due to overflow arithmetics fluxbox crashed.
-rw-r--r--src/Ewmh.cc72
1 files changed, 58 insertions, 14 deletions
diff --git a/src/Ewmh.cc b/src/Ewmh.cc
index 14c74c6..2a9e1ab 100644
--- a/src/Ewmh.cc
+++ b/src/Ewmh.cc
@@ -76,16 +76,30 @@ namespace {
76 * byte being B. The first two cardinals are width, height. Data is in rows, 76 * byte being B. The first two cardinals are width, height. Data is in rows,
77 * left to right and top to bottom. 77 * left to right and top to bottom.
78 * 78 *
79 ***
80 *
81 * NOTE: the returned data for XA_CARDINAL is long if the rfmt equals
82 * 32. sizeof(long) on 64bit machines is 8. to quote from
83 * "man XGetWindowProperty":
84 *
85 * If the returned format is 32, the property data will be stored as
86 * an array of longs (which in a 64-bit application will be 64-bit
87 * values that are padded in the upper 4 bytes).
88 *
89 * this is especially true on 64bit machines when some of the clients
90 * (eg: tvtime, konqueror3) have problems to feed in the right data
91 * into the _NET_WM_ICON property. we faced some segfaults because
92 * width and height were not quite right because of ignoring 64bit
93 * behaviour on client side.
94 *
79 * TODO: maybe move the pixmap-creation code to FbTk? */ 95 * TODO: maybe move the pixmap-creation code to FbTk? */
80void extractNetWmIcon(Atom net_wm_icon, WinClient& winclient) { 96void extractNetWmIcon(Atom net_wm_icon, WinClient& winclient) {
81 97
82 typedef std::pair<int, int> Size; 98 typedef std::pair<int, int> Size;
83 typedef std::map<Size, const unsigned long*> IconContainer; 99 typedef std::map<Size, const unsigned long*> IconContainer;
84 100
85 // attention: the returned data for XA_CARDINAL is long if the rfmt equals
86 // 32. sizeof(long) on 64bit machines is 8.
87 unsigned long* raw_data = 0; 101 unsigned long* raw_data = 0;
88 long nr_icon_data = 0; 102 unsigned long nr_icon_data = 0;
89 103
90 { 104 {
91 Atom rtype; 105 Atom rtype;
@@ -106,7 +120,10 @@ void extractNetWmIcon(Atom net_wm_icon, WinClient& winclient) {
106 120
107 // actually there is some data in _NET_WM_ICON 121 // actually there is some data in _NET_WM_ICON
108 nr_icon_data = nr_bytes_left / sizeof(CARD32); 122 nr_icon_data = nr_bytes_left / sizeof(CARD32);
109 123#ifdef DEBUG
124 std::cerr << "extractNetWmIcon: " << winclient.title() << "\n";
125 std::cerr << "nr_icon_data: " << nr_icon_data << "\n";
126#endif
110 // read all the icons stored in _NET_WM_ICON 127 // read all the icons stored in _NET_WM_ICON
111 if (raw_data) 128 if (raw_data)
112 XFree(raw_data); 129 XFree(raw_data);
@@ -118,30 +135,57 @@ void extractNetWmIcon(Atom net_wm_icon, WinClient& winclient) {
118 135
119 return; 136 return;
120 } 137 }
138#ifdef DEBUG
139 std::cerr << "nr_read: " << nr_read << "|" << nr_bytes_left << "\n";
140#endif
121 } 141 }
122 142
123 IconContainer icon_data; // stores all available data, sorted by size (width x height) 143 IconContainer icon_data; // stores all available data, sorted by size (width x height)
124 int width; 144 unsigned long width;
125 int height; 145 unsigned long height;
126 146
127 // analyze the available icons 147 // analyze the available icons
128 long i; 148 //
129 149 // check also for invalid values coming in from "bad" applications
150 unsigned long i;
130 for (i = 0; i + 2 < nr_icon_data; i += width * height ) { 151 for (i = 0; i + 2 < nr_icon_data; i += width * height ) {
131 152
132 width = raw_data[i++]; 153 width = raw_data[i++];
154 if (width >= nr_icon_data) {
155#ifdef DEBUG
156 std::cerr << "Ewmh.cc extractNetWmIcon found strange _NET_WM_ICON width ("
157 << width << ") for " << winclient.title() << "\n";
158#endif
159 break;
160 }
161
133 height = raw_data[i++]; 162 height = raw_data[i++];
163 if (height >= nr_icon_data) {
164#ifdef DEBUG
165 std::cerr << "Ewmh.cc extractNetWmIcon found strange _NET_WM_ICON height ("
166 << height << ") for " << winclient.title() << "\n";
167#endif
168 break;
169 }
134 170
135 // strange values stored in the NETWM_ICON 171 // strange values stored in the NETWM_ICON
136 if (width <= 0 || height <= 0 || i + width * height > nr_icon_data) { 172 if (i + width * height > nr_icon_data) {
137 std::cerr << "Ewmh.cc extractNetWmIcon found strange _NET_WM_ICON dimensions for " << winclient.title() << "\n"; 173#ifdef DEBUG
138 XFree(raw_data); 174 std::cerr << "Ewmh.cc extractNetWmIcon found strange _NET_WM_ICON dimensions ("
139 return; 175 << width << "x" << height << ")for " << winclient.title() << "\n";
176#endif
177 break;
140 } 178 }
141 179
142 icon_data[Size(width, height)] = &raw_data[i]; 180 icon_data[Size(width, height)] = &raw_data[i];
143 } 181 }
144 182
183 // no valid icons found at all
184 if (icon_data.empty()) {
185 XFree(raw_data);
186 return;
187 }
188
145 Display* dpy = FbTk::App::instance()->display(); 189 Display* dpy = FbTk::App::instance()->display();
146 int scrn = winclient.screen().screenNumber(); 190 int scrn = winclient.screen().screenNumber();
147 191
@@ -178,8 +222,8 @@ void extractNetWmIcon(Atom net_wm_icon, WinClient& winclient) {
178 const unsigned long* src = icon_data.begin()->second; 222 const unsigned long* src = icon_data.begin()->second;
179 unsigned int rgba; 223 unsigned int rgba;
180 unsigned long pixel; 224 unsigned long pixel;
181 int x; 225 unsigned long x;
182 int y; 226 unsigned long y;
183 unsigned char r, g, b, a; 227 unsigned char r, g, b, a;
184 228
185 for (y = 0; y < height; y++) { 229 for (y = 0; y < height; y++) {