protocol-xiqueryversion.c (9313B)
1 /** 2 * Copyright © 2009 Red Hat, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24 /* Test relies on assert() */ 25 #undef NDEBUG 26 27 #ifdef HAVE_DIX_CONFIG_H 28 #include <dix-config.h> 29 #endif 30 31 /* 32 * Protocol testing for XIQueryVersion request and reply. 33 * 34 * Test approach: 35 * Wrap WriteToClient to intercept the server's reply. 36 * Repeatedly test a client/server version combination, compare version in 37 * reply with versions given. Version must be equal to either 38 * server version or client version, whichever is smaller. 39 * Client version less than 2 must return BadValue. 40 */ 41 42 #include <stdint.h> 43 #include <X11/X.h> 44 #include <X11/Xproto.h> 45 #include <X11/extensions/XI2proto.h> 46 #include "inputstr.h" 47 #include "extinit.h" /* for XInputExtensionInit */ 48 #include "scrnintstr.h" 49 #include "xiqueryversion.h" 50 #include "protocol-common.h" 51 #include "exglobals.h" 52 53 extern XExtensionVersion XIVersion; 54 55 struct test_data { 56 int major_client; 57 int minor_client; 58 int major_server; 59 int minor_server; 60 int major_expected; 61 int minor_expected; 62 }; 63 64 extern ClientRec client_window; 65 66 static void 67 reply_XIQueryVersion(ClientPtr client, int len, char *data, void *closure) 68 { 69 xXIQueryVersionReply *rep = (xXIQueryVersionReply *) data; 70 struct test_data *versions = (struct test_data *) closure; 71 unsigned int sver, cver, ver; 72 73 if (client->swapped) { 74 swapl(&rep->length); 75 swaps(&rep->sequenceNumber); 76 swaps(&rep->major_version); 77 swaps(&rep->minor_version); 78 } 79 80 reply_check_defaults(rep, len, XIQueryVersion); 81 82 assert(rep->length == 0); 83 84 sver = versions->major_server * 1000 + versions->minor_server; 85 cver = versions->major_client * 1000 + versions->minor_client; 86 ver = rep->major_version * 1000 + rep->minor_version; 87 88 assert(ver >= 2000); 89 assert((sver > cver) ? ver == cver : ver == sver); 90 } 91 92 static void 93 reply_XIQueryVersion_multiple(ClientPtr client, int len, char *data, void *closure) 94 { 95 xXIQueryVersionReply *rep = (xXIQueryVersionReply *) data; 96 struct test_data *versions = (struct test_data *) closure; 97 98 reply_check_defaults(rep, len, XIQueryVersion); 99 assert(rep->length == 0); 100 101 assert(versions->major_expected == rep->major_version); 102 assert(versions->minor_expected == rep->minor_version); 103 } 104 105 /** 106 * Run a single test with server version smaj.smin and client 107 * version cmaj.cmin. Verify that return code is equal to 'error'. 108 * 109 * Test is run normal, then for a swapped client. 110 */ 111 static void 112 request_XIQueryVersion(int smaj, int smin, int cmaj, int cmin, int error) 113 { 114 int rc; 115 struct test_data versions; 116 xXIQueryVersionReq request; 117 ClientRec client; 118 119 request_init(&request, XIQueryVersion); 120 client = init_client(request.length, &request); 121 global_userdata = (void *) &versions; 122 123 /* Change the server to support smaj.smin */ 124 XIVersion.major_version = smaj; 125 XIVersion.minor_version = smin; 126 127 /* remember versions we send and expect */ 128 versions.major_client = cmaj; 129 versions.minor_client = cmin; 130 versions.major_server = XIVersion.major_version; 131 versions.minor_server = XIVersion.minor_version; 132 133 request.major_version = versions.major_client; 134 request.minor_version = versions.minor_client; 135 rc = ProcXIQueryVersion(&client); 136 assert(rc == error); 137 138 client = init_client(request.length, &request); 139 client.swapped = TRUE; 140 141 swaps(&request.length); 142 swaps(&request.major_version); 143 swaps(&request.minor_version); 144 145 rc = SProcXIQueryVersion(&client); 146 assert(rc == error); 147 } 148 149 /* Client version less than 2.0 must return BadValue, all other combinations 150 * Success */ 151 static void 152 test_XIQueryVersion(void) 153 { 154 reply_handler = reply_XIQueryVersion; 155 156 printf("Server version 2.0 - client versions [1..3].0\n"); 157 /* some simple tests to catch common errors quickly */ 158 request_XIQueryVersion(2, 0, 1, 0, BadValue); 159 request_XIQueryVersion(2, 0, 2, 0, Success); 160 request_XIQueryVersion(2, 0, 3, 0, Success); 161 162 printf("Server version 3.0 - client versions [1..3].0\n"); 163 request_XIQueryVersion(3, 0, 1, 0, BadValue); 164 request_XIQueryVersion(3, 0, 2, 0, Success); 165 request_XIQueryVersion(3, 0, 3, 0, Success); 166 167 printf("Server version 2.0 - client versions [1..3].[1..3]\n"); 168 request_XIQueryVersion(2, 0, 1, 1, BadValue); 169 request_XIQueryVersion(2, 0, 2, 2, Success); 170 request_XIQueryVersion(2, 0, 3, 3, Success); 171 172 printf("Server version 2.2 - client versions [1..3].0\n"); 173 request_XIQueryVersion(2, 2, 1, 0, BadValue); 174 request_XIQueryVersion(2, 2, 2, 0, Success); 175 request_XIQueryVersion(2, 2, 3, 0, Success); 176 177 #if 0 178 /* this one takes a while */ 179 unsigned int cmin, cmaj, smin, smaj; 180 181 printf("Testing all combinations.\n"); 182 for (smaj = 2; smaj <= 0xFFFF; smaj++) 183 for (smin = 0; smin <= 0xFFFF; smin++) 184 for (cmin = 0; cmin <= 0xFFFF; cmin++) 185 for (cmaj = 0; cmaj <= 0xFFFF; cmaj++) { 186 int error = (cmaj < 2) ? BadValue : Success; 187 188 request_XIQueryVersion(smaj, smin, cmaj, cmin, error); 189 } 190 191 #endif 192 193 reply_handler = NULL; 194 } 195 196 197 static void 198 test_XIQueryVersion_multiple(void) 199 { 200 xXIQueryVersionReq request; 201 ClientRec client; 202 XIClientPtr pXIClient; 203 struct test_data versions; 204 int rc; 205 206 request_init(&request, XIQueryVersion); 207 client = init_client(request.length, &request); 208 209 /* Change the server to support 2.2 */ 210 XIVersion.major_version = 2; 211 XIVersion.minor_version = 2; 212 213 reply_handler = reply_XIQueryVersion_multiple; 214 global_userdata = (void *) &versions; 215 216 /* run 1 */ 217 218 /* client is lower than server, nonexpected */ 219 versions.major_expected = request.major_version = 2; 220 versions.minor_expected = request.minor_version = 1; 221 rc = ProcXIQueryVersion(&client); 222 assert(rc == Success); 223 224 /* client is higher than server, no change */ 225 request.major_version = 2; 226 request.minor_version = 3; 227 rc = ProcXIQueryVersion(&client); 228 assert(rc == Success); 229 230 /* client tries to set higher version, stays same */ 231 request.major_version = 2; 232 request.minor_version = 2; 233 rc = ProcXIQueryVersion(&client); 234 assert(rc == Success); 235 236 /* client tries to set lower version, no change */ 237 request.major_version = 2; 238 request.minor_version = 0; 239 rc = ProcXIQueryVersion(&client); 240 assert(rc == BadValue); 241 242 /* run 2 */ 243 client = init_client(request.length, &request); 244 XIVersion.major_version = 2; 245 XIVersion.minor_version = 3; 246 247 versions.major_expected = request.major_version = 2; 248 versions.minor_expected = request.minor_version = 2; 249 rc = ProcXIQueryVersion(&client); 250 assert(rc == Success); 251 252 /* client bumps version from 2.2 to 2.3 */ 253 request.major_version = 2; 254 versions.minor_expected = request.minor_version = 3; 255 rc = ProcXIQueryVersion(&client); 256 assert(rc == Success); 257 258 /* real version is changed, too! */ 259 pXIClient = dixLookupPrivate(&client.devPrivates, XIClientPrivateKey); 260 assert(pXIClient->minor_version == 3); 261 262 /* client tries to set lower version, no change */ 263 request.major_version = 2; 264 request.minor_version = 1; 265 rc = ProcXIQueryVersion(&client); 266 assert(rc == BadValue); 267 268 /* run 3 */ 269 client = init_client(request.length, &request); 270 XIVersion.major_version = 2; 271 XIVersion.minor_version = 3; 272 273 versions.major_expected = request.major_version = 2; 274 versions.minor_expected = request.minor_version = 3; 275 rc = ProcXIQueryVersion(&client); 276 assert(rc == Success); 277 278 request.major_version = 2; 279 versions.minor_expected = request.minor_version = 2; 280 rc = ProcXIQueryVersion(&client); 281 assert(rc == Success); 282 283 /* but real client version must not be lowered */ 284 pXIClient = dixLookupPrivate(&client.devPrivates, XIClientPrivateKey); 285 assert(pXIClient->minor_version == 3); 286 287 request.major_version = 2; 288 request.minor_version = 1; 289 rc = ProcXIQueryVersion(&client); 290 assert(rc == BadValue); 291 } 292 293 int 294 protocol_xiqueryversion_test(void) 295 { 296 init_simple(); 297 298 test_XIQueryVersion(); 299 test_XIQueryVersion_multiple(); 300 301 return 0; 302 }