1 /* 2 * Unit test suite for *scanf functions. 3 * 4 * Copyright 2002 Uwe Bonnes 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include "precomp.h" 22 23 static void test_sscanf( void ) 24 { 25 char buffer[100], buffer1[100]; 26 char format[20]; 27 int result, ret; 28 LONGLONG result64; 29 char c; 30 void *ptr; 31 float res1= -82.6267f, res2= 27.76f, res11, res12; 32 double double_res; 33 static const char pname[]=" St. Petersburg, Florida\n"; 34 int hour=21,min=59,sec=20; 35 int number,number_so_far; 36 37 38 /* check EOF */ 39 strcpy(buffer,""); 40 ret = sscanf(buffer, "%d", &result); 41 ok( ret == EOF,"sscanf returns %x instead of %x\n", ret, EOF ); 42 43 /* check %p */ 44 ok( sscanf("000000000046F170", "%p", &ptr) == 1, "sscanf failed\n" ); 45 ok( ptr == (void *)0x46F170,"sscanf reads %p instead of %x\n", ptr, 0x46F170 ); 46 47 ok( sscanf("0046F171", "%p", &ptr) == 1, "sscanf failed\n" ); 48 ok( ptr == (void *)0x46F171,"sscanf reads %p instead of %x\n", ptr, 0x46F171 ); 49 50 ok( sscanf("46F172", "%p", &ptr) == 1, "sscanf failed\n" ); 51 ok( ptr == (void *)0x46F172,"sscanf reads %p instead of %x\n", ptr, 0x46F172 ); 52 53 ok( sscanf("0x46F173", "%p", &ptr) == 1, "sscanf failed\n" ); 54 ok( ptr == NULL,"sscanf reads %p instead of %x\n", ptr, 0 ); 55 56 ok( sscanf("-46F174", "%p", &ptr) == 1, "sscanf failed\n" ); 57 ok( ptr == (void *)(ULONG_PTR)-0x46f174,"sscanf reads %p instead of %p\n", 58 ptr, (void *)(ULONG_PTR)-0x46f174 ); 59 60 ok( sscanf("+46F175", "%p", &ptr) == 1, "sscanf failed\n" ); 61 ok( ptr == (void *)0x46F175,"sscanf reads %p instead of %x\n", ptr, 0x46F175 ); 62 63 /* check %p with no hex digits */ 64 ok( sscanf("1233", "%p", &ptr) == 1, "sscanf failed\n" ); 65 ok( ptr == (void *)0x1233,"sscanf reads %p instead of %x\n", ptr, 0x1233 ); 66 67 ok( sscanf("1234", "%P", &ptr) == 1, "sscanf failed\n" ); 68 ok( ptr == (void *)0x1234,"sscanf reads %p instead of %x\n", ptr, 0x1234 ); 69 70 /* check %x */ 71 strcpy(buffer,"0x519"); 72 ok( sscanf(buffer, "%x", &result) == 1, "sscanf failed\n" ); 73 ok( result == 0x519,"sscanf reads %x instead of %x\n", result, 0x519 ); 74 75 strcpy(buffer,"0x51a"); 76 ok( sscanf(buffer, "%x", &result) == 1, "sscanf failed\n" ); 77 ok( result == 0x51a ,"sscanf reads %x instead of %x\n", result, 0x51a ); 78 79 strcpy(buffer,"0x51g"); 80 ok( sscanf(buffer, "%x", &result) == 1, "sscanf failed\n" ); 81 ok( result == 0x51, "sscanf reads %x instead of %x\n", result, 0x51 ); 82 83 result = 0; 84 ret = sscanf("-1", "%x", &result); 85 ok(ret == 1, "Wrong number of arguments read: %d (expected 1)\n", ret); 86 ok(result == -1, "Read %d, expected -1\n", result); 87 88 /* check % followed by any char */ 89 strcpy(buffer,"\"%12@"); 90 strcpy(format,"%\"%%%d%@"); /* work around gcc format check */ 91 ok( sscanf(buffer, format, &result) == 1, "sscanf failed\n" ); 92 ok( result == 12, "sscanf reads %x instead of %x\n", result, 12 ); 93 94 /* Check float */ 95 ret = sprintf(buffer,"%f %f",res1, res2); 96 ok( ret == 20, "expected 20, got %u\n", ret); 97 ret = sscanf(buffer,"%f%f",&res11, &res12); 98 ok( ret == 2, "expected 2, got %u\n", ret); 99 ok( (res11 == res1) && (res12 == res2), "Error reading floats\n"); 100 101 /* Check double */ 102 ret = sprintf(buffer, "%lf", 32.715); 103 ok(ret == 9, "expected 9, got %u\n", ret); 104 ret = sscanf(buffer, "%lf", &double_res); 105 ok(ret == 1, "expected 1, got %u\n", ret); 106 ok(double_res == 32.715, "Got %lf, expected %lf\n", double_res, 32.715); 107 ret = sscanf(buffer, "%Lf", &double_res); 108 ok(ret == 1, "expected 1, got %u\n", ret); 109 ok(double_res == 32.715, "Got %lf, expected %lf\n", double_res, 32.715); 110 111 strcpy(buffer, "1.1e-30"); 112 ret = sscanf(buffer, "%lf", &double_res); 113 ok(ret == 1, "expected 1, got %u\n", ret); 114 ok(double_res >= 1.1e-30-1e-45 && double_res <= 1.1e-30+1e-45, 115 "Got %.18le, expected %.18le\n", double_res, 1.1e-30); 116 117 /* check strings */ 118 ret = sprintf(buffer," %s", pname); 119 ok( ret == 26, "expected 26, got %u\n", ret); 120 ret = sscanf(buffer,"%*c%[^\n]",buffer1); 121 ok( ret == 1, "Error with format \"%s\"\n","%*c%[^\n]"); 122 ok( strncmp(pname,buffer1,strlen(buffer1)) == 0, "Error with \"%s\" \"%s\"\n",pname, buffer1); 123 124 ret = sscanf("abcefgdh","%*[a-cg-e]%c",&buffer[0]); 125 ok( ret == 1, "Error with format \"%s\"\n","%*[a-cg-e]%c"); 126 ok( buffer[0] == 'd', "Error with \"abcefgdh\" \"%c\"\n", buffer[0]); 127 128 ret = sscanf("abcefgdh","%*[a-cd-dg-e]%c",&buffer[0]); 129 ok( ret == 1, "Error with format \"%s\"\n","%*[a-cd-dg-e]%c"); 130 ok( buffer[0] == 'h', "Error with \"abcefgdh\" \"%c\"\n", buffer[0]); 131 132 buffer1[0] = 'b'; 133 ret = sscanf("a","%s%s", buffer, buffer1); 134 ok( ret == 1, "expected 1, got %u\n", ret); 135 ok( buffer[0] == 'a', "buffer[0] = '%c'\n", buffer[0]); 136 ok( buffer[1] == '\0', "buffer[1] = '%c'\n", buffer[1]); 137 ok( buffer1[0] == 'b', "buffer1[0] = '%c'\n", buffer1[0]); 138 139 /* check digits */ 140 ret = sprintf(buffer,"%d:%d:%d",hour,min,sec); 141 ok( ret == 8, "expected 8, got %u\n", ret); 142 ret = sscanf(buffer,"%d%n",&number,&number_so_far); 143 ok(ret == 1 , "problem with format arg \"%%d%%n\"\n"); 144 ok(number == hour,"Read wrong arg %d instead of %d\n",number, hour); 145 ok(number_so_far == 2,"Read wrong arg for \"%%n\" %d instead of 2\n",number_so_far); 146 147 ret = sscanf(buffer+2,"%*c%n",&number_so_far); 148 ok(ret == 0 , "problem with format arg \"%%*c%%n\"\n"); 149 ok(number_so_far == 1,"Read wrong arg for \"%%n\" %d instead of 2\n",number_so_far); 150 151 result = 0xdeadbeef; 152 strcpy(buffer,"12345678"); 153 ret = sscanf(buffer, "%hd", &result); 154 ok(ret == 1, "Wrong number of arguments read: %d\n", ret); 155 ok(result == 0xdead614e, "Wrong number read (%x)\n", result); 156 157 result = 0xdeadbeef; 158 ret = sscanf(buffer, "%hhd", &result); 159 ok(ret == 1, "Wrong number of arguments read: %d\n", ret); 160 ok(result == 0xbc614e, "Wrong number read (%x)\n", result); 161 162 strcpy(buffer,"12345678901234"); 163 ret = sscanf(buffer, "%lld", &result64); 164 ok(ret == 1, "Wrong number of arguments read: %d\n", ret); 165 ret = sprintf(buffer1, "%lld", result64); 166 ok(ret==14 || broken(ret==10), "sprintf returned %d\n", ret); 167 if(ret == 14) 168 ok(!strcmp(buffer, buffer1), "got %s, expected %s\n", buffer1, buffer); 169 170 /* Check %i according to bug 1878 */ 171 strcpy(buffer,"123"); 172 ret = sscanf(buffer, "%i", &result); 173 ok(ret == 1, "Wrong number of arguments read: %d\n", ret); 174 ok(result == 123, "Wrong number read\n"); 175 result = 0; 176 ret = sscanf("-1", "%i", &result); 177 ok(ret == 1, "Wrong number of arguments read: %d (expected 1)\n", ret); 178 ok(result == -1, "Read %d, expected -1\n", result); 179 ret = sscanf(buffer, "%d", &result); 180 ok(ret == 1, "Wrong number of arguments read: %d\n", ret); 181 ok(result == 123, "Wrong number read\n"); 182 result = 0; 183 ret = sscanf("-1", "%d", &result); 184 ok(ret == 1, "Wrong number of arguments read: %d (expected 1)\n", ret); 185 ok(result == -1, "Read %d, expected -1\n", result); 186 187 /* Check %i for octal and hexadecimal input */ 188 result = 0; 189 strcpy(buffer,"017"); 190 ret = sscanf(buffer, "%i", &result); 191 ok(ret == 1, "Wrong number of arguments read: %d\n", ret); 192 ok(result == 15, "Wrong number read\n"); 193 result = 0; 194 strcpy(buffer,"0x17"); 195 ret = sscanf(buffer, "%i", &result); 196 ok(ret == 1, "Wrong number of arguments read: %d\n", ret); 197 ok(result == 23, "Wrong number read\n"); 198 199 /* %o */ 200 result = 0; 201 ret = sscanf("-1", "%o", &result); 202 ok(ret == 1, "Wrong number of arguments read: %d (expected 1)\n", ret); 203 ok(result == -1, "Read %d, expected -1\n", result); 204 205 /* %u */ 206 result = 0; 207 ret = sscanf("-1", "%u", &result); 208 ok(ret == 1, "Wrong number of arguments read: %d (expected 1)\n", ret); 209 ok(result == -1, "Read %d, expected -1\n", result); 210 211 /* Check %c */ 212 strcpy(buffer,"a"); 213 c = 0x55; 214 ret = sscanf(buffer, "%c", &c); 215 ok(ret == 1, "Wrong number of arguments read: %d\n", ret); 216 ok(c == 'a', "Field incorrect: '%c'\n", c); 217 218 strcpy(buffer," a"); 219 c = 0x55; 220 ret = sscanf(buffer, "%c", &c); 221 ok(ret == 1, "Wrong number of arguments read: %d\n", ret); 222 ok(c == ' ', "Field incorrect: '%c'\n", c); 223 224 strcpy(buffer,"18:59"); 225 c = 0x55; 226 ret = sscanf(buffer, "%d:%d%c", &hour, &min, &c); 227 ok(ret == 2, "Wrong number of arguments read: %d\n", ret); 228 ok(hour == 18, "Field 1 incorrect: %d\n", hour); 229 ok(min == 59, "Field 2 incorrect: %d\n", min); 230 ok(c == 0x55, "Field 3 incorrect: 0x%02x\n", c); 231 232 /* Check %n (also whitespace in format strings and %s) */ 233 buffer[0]=0; buffer1[0]=0; 234 ret = sscanf("abc def", "%s %n%s", buffer, &number_so_far, buffer1); 235 ok(strcmp(buffer, "abc")==0, "First %%s read incorrectly: %s\n", buffer); 236 ok(strcmp(buffer1,"def")==0, "Second %%s read incorrectly: %s\n", buffer1); 237 ok(number_so_far==6, "%%n yielded wrong result: %d\n", number_so_far); 238 ok(ret == 2, "%%n shouldn't count as a conversion: %d\n", ret); 239 240 /* Check where %n matches to EOF in buffer */ 241 strcpy(buffer, "3:45"); 242 ret = sscanf(buffer, "%d:%d%n", &hour, &min, &number_so_far); 243 ok(ret == 2, "Wrong number of arguments read: %d\n", ret); 244 ok(number_so_far == 4, "%%n yielded wrong result: %d\n", number_so_far); 245 246 buffer[0] = 0; 247 buffer1[0] = 0; 248 ret = sscanf("test=value\xda", "%[^=] = %[^;]", buffer, buffer1); 249 ok(ret == 2, "got %d\n", ret); 250 ok(!strcmp(buffer, "test"), "buf %s\n", buffer); 251 ok(!strcmp(buffer1, "value\xda"), "buf %s\n", buffer1); 252 253 ret = sscanf("\x81\x82test", "\x81%\x82%s", buffer); 254 ok(ret == 1, "got %d\n", ret); 255 ok(!strcmp(buffer, "test"), "buf = %s\n", buffer); 256 } 257 258 static void test_sscanf_s(void) 259 { 260 int (WINAPIV *psscanf_s)(const char*,const char*,...); 261 HMODULE hmod = GetModuleHandleA("msvcrt.dll"); 262 int i, ret; 263 char buf[100]; 264 265 psscanf_s = (void*)GetProcAddress(hmod, "sscanf_s"); 266 if(!psscanf_s) { 267 win_skip("sscanf_s not available\n"); 268 return; 269 } 270 271 ret = psscanf_s("123", "%d", &i); 272 ok(ret == 1, "Wrong number of arguments read: %d\n", ret); 273 ok(i == 123, "i = %d\n", i); 274 275 ret = psscanf_s("123", "%s", buf, 100); 276 ok(ret == 1, "Wrong number of arguments read: %d\n", ret); 277 ok(!strcmp("123", buf), "buf = %s\n", buf); 278 279 ret = psscanf_s("123", "%s", buf, 3); 280 ok(ret == 0, "Wrong number of arguments read: %d\n", ret); 281 ok(buf[0]=='\0', "buf = %s\n", buf); 282 283 buf[0] = 'a'; 284 ret = psscanf_s("123", "%3c", buf, 2); 285 ok(ret == 0, "Wrong number of arguments read: %d\n", ret); 286 ok(buf[0]=='\0', "buf = %s\n", buf); 287 288 i = 1; 289 ret = psscanf_s("123 123", "%s %d", buf, 2, &i); 290 ok(ret == 0, "Wrong number of arguments read: %d\n", ret); 291 ok(i==1, "i = %d\n", i); 292 293 i = 1; 294 ret = psscanf_s("123 123", "%d %s", &i, buf, 2); 295 ok(ret == 1, "Wrong number of arguments read: %d\n", ret); 296 ok(i==123, "i = %d\n", i); 297 } 298 299 static void test_swscanf( void ) 300 { 301 wchar_t buffer[100]; 302 int result, ret; 303 static const WCHAR formatd[] = {'%','d',0}; 304 const WCHAR format2[] = {'a',0x1234,'%',0x1234,'%','c',0}; 305 WCHAR c; 306 307 /* check WEOF */ 308 /* WEOF is an unsigned short -1 but swscanf returns int 309 so it should be sign-extended */ 310 buffer[0] = 0; 311 ret = swscanf(buffer, formatd, &result); 312 /* msvcrt returns 0 but should return -1 (later versions do) */ 313 ok( ret == (short)WEOF || broken(ret == 0), 314 "swscanf returns %x instead of %x\n", ret, WEOF ); 315 316 buffer[0] = 'a'; 317 buffer[1] = 0x1234; 318 buffer[2] = 0x1234; 319 buffer[3] = 'b'; 320 ret = swscanf(buffer, format2, &c); 321 ok(ret == 1, "swscanf returned %d\n", ret); 322 ok(c == 'b', "c = %x\n", c); 323 } 324 325 static void test_swscanf_s(void) 326 { 327 static const wchar_t fmt1[] = {'%','c',0}; 328 static const wchar_t fmt2[] = {'%','[','a','-','z',']',0}; 329 330 int (WINAPIV *pswscanf_s)(const wchar_t*,const wchar_t*,...); 331 HMODULE hmod = GetModuleHandleA("msvcrt.dll"); 332 wchar_t buf[2], out[2]; 333 int ret; 334 335 pswscanf_s = (void*)GetProcAddress(hmod, "swscanf_s"); 336 if(!pswscanf_s) { 337 win_skip("swscanf_s not available\n"); 338 return; 339 } 340 341 buf[0] = 'a'; 342 buf[1] = '1'; 343 out[1] = 'b'; 344 ret = pswscanf_s(buf, fmt1, out, 1); 345 ok(ret == 1, "swscanf_s returned %d\n", ret); 346 ok(out[0] == 'a', "out[0] = %x\n", out[0]); 347 ok(out[1] == 'b', "out[1] = %x\n", out[1]); 348 349 ret = pswscanf_s(buf, fmt2, out, 1); 350 ok(!ret, "swscanf_s returned %d\n", ret); 351 352 ret = pswscanf_s(buf, fmt2, out, 2); 353 ok(ret == 1, "swscanf_s returned %d\n", ret); 354 ok(out[0] == 'a', "out[0] = %x\n", out[0]); 355 ok(!out[1], "out[1] = %x\n", out[1]); 356 } 357 358 START_TEST(scanf) 359 { 360 test_sscanf(); 361 test_sscanf_s(); 362 test_swscanf(); 363 test_swscanf_s(); 364 } 365