1#!/usr/bin/env python3 2# Copyright 2022 The Pigweed Authors 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); you may not 5# use this file except in compliance with the License. You may obtain a copy of 6# the License at 7# 8# https://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13# License for the specific language governing permissions and limitations under 14# the License. 15"""Tests the tokenized string decode module.""" 16 17from datetime import datetime 18import math 19import unittest 20 21import tokenized_string_decoding_test_data as tokenized_string 22import varint_test_data 23from pw_tokenizer import decode 24from pw_tokenizer import encode 25 26 27def error(msg, value=None) -> str: 28 """Formats msg as the message for an argument that failed to parse.""" 29 if value is None: 30 return '<[{}]>'.format(msg) 31 return '<[{} ({})]>'.format(msg, value) 32 33 34class TestDecodeTokenized(unittest.TestCase): 35 """Tests decoding tokenized strings with various arguments.""" 36 37 def test_decode_generated_data(self) -> None: 38 self.assertGreater(len(tokenized_string.TEST_DATA), 100) 39 40 for fmt, decoded, encoded in tokenized_string.TEST_DATA: 41 self.assertEqual(decode.decode(fmt, encoded, True), decoded) 42 43 def test_unicode_decode_errors(self) -> None: 44 """Tests unicode errors, which do not occur in the C++ decoding code.""" 45 self.assertEqual( 46 decode.decode('Why, %c', b'\x01', True), 47 'Why, ' + error('%c ERROR', -1), 48 ) 49 50 self.assertEqual( 51 decode.decode('%sXY%+ldxy%u', b'\x83N\x80!\x01\x02', True), 52 '{}XY{}xy{}'.format( 53 error('%s ERROR', "'N\\x80!'"), 54 error('%+ld SKIPPED', -1), 55 error('%u SKIPPED', 1), 56 ), 57 ) 58 59 self.assertEqual( 60 decode.decode('%s%lld%9u', b'\x82$\x80\x80', True), 61 '{0}{1}{2}'.format( 62 error("%s ERROR ('$\\x80')"), 63 error('%lld SKIPPED'), 64 error('%9u SKIPPED'), 65 ), 66 ) 67 68 self.assertEqual( 69 decode.decode('%c', b'\xff\xff\xff\xff\x0f', True), 70 error('%c ERROR', -2147483648), 71 ) 72 73 def test_ignore_errors(self) -> None: 74 self.assertEqual(decode.decode('Why, %c', b'\x01'), 'Why, %c') 75 76 self.assertEqual(decode.decode('%s %d', b'\x01!'), '! %d') 77 78 def test_pointer(self) -> None: 79 """Tests pointer args, which are not natively supported in Python.""" 80 self.assertEqual( 81 decode.decode('Hello: %p', b'\x00', True), 'Hello: 0x00000000' 82 ) 83 self.assertEqual( 84 decode.decode('%p%d%d', b'\x02\x80', True), 85 '0x00000001<[%d ERROR]><[%d SKIPPED]>', 86 ) 87 88 def test_nothing_printed_fails(self) -> None: 89 result = decode.FormatString('%n').format(b'') 90 self.assertFalse(result.ok()) 91 92 93class TestPercentLiteralDecoding(unittest.TestCase): 94 """Tests decoding the %-literal in various invalid situations.""" 95 96 def test_percent(self) -> None: 97 result = decode.FormatString('%%').format(b'') 98 self.assertTrue(result.ok()) 99 self.assertEqual(result.value, '%') 100 self.assertEqual(result.remaining, b'') 101 102 def test_percent_with_leading_plus_fails(self) -> None: 103 result = decode.FormatString('%+%').format(b'') 104 self.assertFalse(result.ok()) 105 self.assertEqual(result.remaining, b'') 106 107 def test_percent_with_leading_negative(self) -> None: 108 result = decode.FormatString('%-%').format(b'') 109 self.assertFalse(result.ok()) 110 self.assertEqual(result.remaining, b'') 111 112 def test_percent_with_leading_space(self) -> None: 113 result = decode.FormatString('% %').format(b'') 114 self.assertFalse(result.ok()) 115 self.assertEqual(result.remaining, b'') 116 117 def test_percent_with_leading_hashtag(self) -> None: 118 result = decode.FormatString('%#%').format(b'') 119 self.assertFalse(result.ok()) 120 self.assertEqual(result.remaining, b'') 121 122 def test_percent_with_leading_zero(self) -> None: 123 result = decode.FormatString('%0%').format(b'') 124 self.assertFalse(result.ok()) 125 self.assertEqual(result.remaining, b'') 126 127 def test_percent_with_length(self) -> None: 128 """Test that all length prefixes fail to decode with %.""" 129 130 result = decode.FormatString('%hh%').format(b'') 131 self.assertFalse(result.ok()) 132 self.assertEqual(result.remaining, b'') 133 134 result = decode.FormatString('%h%').format(b'') 135 self.assertFalse(result.ok()) 136 self.assertEqual(result.remaining, b'') 137 138 result = decode.FormatString('%l%').format(b'') 139 self.assertFalse(result.ok()) 140 self.assertEqual(result.remaining, b'') 141 142 result = decode.FormatString('%ll%').format(b'') 143 self.assertFalse(result.ok()) 144 self.assertEqual(result.remaining, b'') 145 146 result = decode.FormatString('%L%').format(b'') 147 self.assertFalse(result.ok()) 148 self.assertEqual(result.remaining, b'') 149 150 result = decode.FormatString('%j%').format(b'') 151 self.assertFalse(result.ok()) 152 self.assertEqual(result.remaining, b'') 153 154 result = decode.FormatString('%z%').format(b'') 155 self.assertFalse(result.ok()) 156 self.assertEqual(result.remaining, b'') 157 158 result = decode.FormatString('%t%').format(b'') 159 self.assertFalse(result.ok()) 160 self.assertEqual(result.remaining, b'') 161 162 def test_percent_with_width(self): 163 result = decode.FormatString('%9%').format(b'') 164 self.assertFalse(result.ok()) 165 166 def test_percent_with_multidigit_width(self): 167 result = decode.FormatString('%10%').format(b'') 168 self.assertFalse(result.ok()) 169 170 def test_percent_with_star_width(self): 171 result = decode.FormatString('%*%').format(b'') 172 self.assertFalse(result.ok()) 173 174 def test_percent_with_precision(self): 175 result = decode.FormatString('%.5%').format(b'') 176 self.assertFalse(result.ok()) 177 178 def test_percent_with_multidigit_precision(self): 179 result = decode.FormatString('%.10%').format(b'') 180 self.assertFalse(result.ok()) 181 182 def test_percent_with_star_precision(self): 183 result = decode.FormatString('%.*%').format(b'') 184 self.assertFalse(result.ok()) 185 186 187# pylint: disable=too-many-public-methods 188class TestIntegerDecoding(unittest.TestCase): 189 """Tests decoding variable-length integers.""" 190 191 def test_signed_integer_d(self) -> None: 192 result = decode.FormatString('%d').format(encode.encode_args(-10)) 193 self.assertTrue(result.ok()) 194 self.assertEqual(result.value, '-10') 195 self.assertEqual(result.remaining, b'') 196 197 def test_signed_integer_d_with_minus(self) -> None: 198 result = decode.FormatString('%-5d').format(encode.encode_args(10)) 199 self.assertTrue(result.ok()) 200 self.assertEqual(result.value, '10 ') 201 self.assertEqual(result.remaining, b'') 202 203 def test_signed_integer_d_with_plus(self) -> None: 204 result = decode.FormatString('%+d').format(encode.encode_args(10)) 205 self.assertTrue(result.ok()) 206 self.assertEqual(result.value, '+10') 207 self.assertEqual(result.remaining, b'') 208 209 def test_signed_integer_d_with_blank_space(self) -> None: 210 result = decode.FormatString('% d').format(encode.encode_args(10)) 211 self.assertTrue(result.ok()) 212 self.assertEqual(result.value, ' 10') 213 self.assertEqual(result.remaining, b'') 214 215 def test_signed_integer_d_with_plus_and_blank_space_ignores_blank_space( 216 self, 217 ) -> None: 218 result = decode.FormatString('%+ d').format(encode.encode_args(10)) 219 self.assertTrue(result.ok()) 220 self.assertEqual(result.value, '+10') 221 self.assertEqual(result.remaining, b'') 222 223 result = decode.FormatString('% +d').format(encode.encode_args(10)) 224 self.assertTrue(result.ok()) 225 self.assertEqual(result.value, '+10') 226 self.assertEqual(result.remaining, b'') 227 228 def test_signed_integer_d_with_hashtag(self) -> None: 229 result = decode.FormatString('%#d').format(encode.encode_args(10)) 230 self.assertFalse(result.ok()) 231 232 def test_signed_integer_d_with_zero(self) -> None: 233 result = decode.FormatString('%05d').format(encode.encode_args(10)) 234 self.assertTrue(result.ok()) 235 self.assertEqual(result.value, '00010') 236 self.assertEqual(result.remaining, b'') 237 238 def test_signed_integer_d_with_length(self) -> None: 239 """Tests that length modifiers do not affect signed integer decoding.""" 240 result = decode.FormatString('%hhd').format(encode.encode_args(-10)) 241 self.assertTrue(result.ok()) 242 self.assertEqual(result.value, '-10') 243 self.assertEqual(result.remaining, b'') 244 245 result = decode.FormatString('%hd').format(encode.encode_args(-10)) 246 self.assertTrue(result.ok()) 247 self.assertEqual(result.value, '-10') 248 self.assertEqual(result.remaining, b'') 249 250 result = decode.FormatString('%ld').format(encode.encode_args(-10)) 251 self.assertTrue(result.ok()) 252 self.assertEqual(result.value, '-10') 253 self.assertEqual(result.remaining, b'') 254 255 result = decode.FormatString('%lld').format(encode.encode_args(-10)) 256 self.assertTrue(result.ok()) 257 self.assertEqual(result.value, '-10') 258 self.assertEqual(result.remaining, b'') 259 260 result = decode.FormatString('%jd').format(encode.encode_args(-10)) 261 self.assertTrue(result.ok()) 262 self.assertEqual(result.value, '-10') 263 self.assertEqual(result.remaining, b'') 264 265 result = decode.FormatString('%zd').format(encode.encode_args(-10)) 266 self.assertTrue(result.ok()) 267 self.assertEqual(result.value, '-10') 268 self.assertEqual(result.remaining, b'') 269 270 result = decode.FormatString('%td').format(encode.encode_args(-10)) 271 self.assertTrue(result.ok()) 272 self.assertEqual(result.value, '-10') 273 self.assertEqual(result.remaining, b'') 274 275 def test_signed_integer_d_with_width(self) -> None: 276 result = decode.FormatString('%5d').format(encode.encode_args(-10)) 277 self.assertTrue(result.ok()) 278 self.assertEqual(result.value, ' -10') 279 self.assertEqual(result.remaining, b'') 280 281 def test_signed_integer_d_with_width_and_0_flag(self) -> None: 282 result = decode.FormatString('%05d').format(encode.encode_args(-10)) 283 self.assertTrue(result.ok()) 284 self.assertEqual(result.value, '-0010') 285 286 def test_signed_integer_d_with_multidigit_width(self) -> None: 287 result = decode.FormatString('%10d').format(encode.encode_args(-10)) 288 self.assertTrue(result.ok()) 289 self.assertEqual(result.value, ' -10') 290 291 def test_signed_integer_d_with_star_width(self) -> None: 292 result = decode.FormatString('%*d').format(encode.encode_args(10, -10)) 293 self.assertTrue(result.ok()) 294 self.assertEqual(result.value, ' -10') 295 296 def test_signed_integer_d_with_missing_width_or_value(self) -> None: 297 result = decode.FormatString('%*d').format(encode.encode_args(-10)) 298 self.assertFalse(result.ok()) 299 300 def test_signed_integer_d_with_precision(self) -> None: 301 result = decode.FormatString('%.5d').format(encode.encode_args(-10)) 302 self.assertTrue(result.ok()) 303 self.assertEqual(result.value, '-00010') 304 305 def test_signed_integer_d_with_multidigit_precision(self) -> None: 306 result = decode.FormatString('%.10d').format(encode.encode_args(-10)) 307 self.assertTrue(result.ok()) 308 self.assertEqual(result.value, '-0000000010') 309 310 def test_signed_integer_d_with_star_precision(self) -> None: 311 result = decode.FormatString('%.*d').format(encode.encode_args(10, -10)) 312 self.assertTrue(result.ok()) 313 self.assertEqual(result.value, '-0000000010') 314 315 def test_signed_integer_d_with_zero_precision(self) -> None: 316 result = decode.FormatString('%.0d').format(encode.encode_args(-10)) 317 self.assertTrue(result.ok()) 318 self.assertEqual(result.value, '-10') 319 320 def test_signed_integer_d_with_empty_precision(self) -> None: 321 result = decode.FormatString('%.d').format(encode.encode_args(-10)) 322 self.assertTrue(result.ok()) 323 self.assertEqual(result.value, '-10') 324 325 def test_zero_with_zero_precision(self) -> None: 326 result = decode.FormatString('%.0d').format(encode.encode_args(0)) 327 self.assertTrue(result.ok()) 328 self.assertEqual(result.value, '') 329 330 def test_zero_with_empty_precision(self) -> None: 331 result = decode.FormatString('%.d').format(encode.encode_args(0)) 332 self.assertTrue(result.ok()) 333 self.assertEqual(result.value, '') 334 335 def test_signed_integer_d_with_width_and_precision(self) -> None: 336 result = decode.FormatString('%10.5d').format(encode.encode_args(-10)) 337 self.assertTrue(result.ok()) 338 self.assertEqual(result.value, ' -00010') 339 340 def test_signed_integer_d_with_star_width_and_precision(self) -> None: 341 result = decode.FormatString('%*.*d').format( 342 encode.encode_args(15, 10, -10) 343 ) 344 self.assertTrue(result.ok()) 345 self.assertEqual(result.value, ' -0000000010') 346 347 def test_signed_integer_d_with_missing_precision_or_value(self) -> None: 348 result = decode.FormatString('%.*d').format(encode.encode_args(-10)) 349 self.assertFalse(result.ok()) 350 351 def test_64_bit_specifier_workaround(self) -> None: 352 result = decode.FormatString('%.u%.*lu%0*lu').format( 353 encode.encode_args(0, 0, 0, 0, 0) 354 ) 355 self.assertTrue(result.ok()) 356 self.assertEqual(result.value, '0') 357 self.assertEqual(result.remaining, b'') 358 359 result = decode.FormatString('%.u%.*lu%0*lu').format( 360 encode.encode_args(0, 0, 1, 9, 0) 361 ) 362 self.assertTrue(result.ok()) 363 self.assertEqual(result.value, '1000000000') 364 self.assertEqual(result.remaining, b'') 365 366 result = decode.FormatString('%.u%.*lu%0*lu').format( 367 encode.encode_args(1, 9, 0, 9, 0) 368 ) 369 self.assertTrue(result.ok()) 370 self.assertEqual(result.value, '1000000000000000000') 371 self.assertEqual(result.remaining, b'') 372 373 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 374 375 def test_signed_integer_i(self) -> None: 376 result = decode.FormatString('%i').format(encode.encode_args(-10)) 377 self.assertTrue(result.ok()) 378 self.assertEqual(result.value, '-10') 379 self.assertEqual(result.remaining, b'') 380 381 def test_signed_integer_i_with_minus(self) -> None: 382 result = decode.FormatString('%-5i').format(encode.encode_args(10)) 383 self.assertTrue(result.ok()) 384 self.assertEqual(result.value, '10 ') 385 self.assertEqual(result.remaining, b'') 386 387 def test_signed_integer_i_with_plus(self) -> None: 388 result = decode.FormatString('%+i').format(encode.encode_args(10)) 389 self.assertTrue(result.ok()) 390 self.assertEqual(result.value, '+10') 391 self.assertEqual(result.remaining, b'') 392 393 def test_signed_integer_i_with_blank_space(self) -> None: 394 result = decode.FormatString('% i').format(encode.encode_args(10)) 395 self.assertTrue(result.ok()) 396 self.assertEqual(result.value, ' 10') 397 self.assertEqual(result.remaining, b'') 398 399 def test_signed_integer_i_with_plus_and_blank_space_ignores_blank_space( 400 self, 401 ) -> None: 402 result = decode.FormatString('%+ i').format(encode.encode_args(10)) 403 self.assertTrue(result.ok()) 404 self.assertEqual(result.value, '+10') 405 self.assertEqual(result.remaining, b'') 406 407 result = decode.FormatString('% +i').format(encode.encode_args(10)) 408 self.assertTrue(result.ok()) 409 self.assertEqual(result.value, '+10') 410 self.assertEqual(result.remaining, b'') 411 412 def test_signed_integer_i_with_hashtag(self) -> None: 413 result = decode.FormatString('%#i').format(encode.encode_args(10)) 414 self.assertFalse(result.ok()) 415 self.assertEqual(result.remaining, encode.encode_args(10)) 416 417 def test_signed_integer_i_with_zero(self) -> None: 418 result = decode.FormatString('%05i').format(encode.encode_args(10)) 419 self.assertTrue(result.ok()) 420 self.assertEqual(result.value, '00010') 421 self.assertEqual(result.remaining, b'') 422 423 def test_signed_integer_i_with_length(self) -> None: 424 """Tests that length modifiers do not affect signed integer decoding.""" 425 result = decode.FormatString('%hhi').format(encode.encode_args(-10)) 426 self.assertTrue(result.ok()) 427 self.assertEqual(result.value, '-10') 428 self.assertEqual(result.remaining, b'') 429 430 result = decode.FormatString('%hi').format(encode.encode_args(-10)) 431 self.assertTrue(result.ok()) 432 self.assertEqual(result.value, '-10') 433 self.assertEqual(result.remaining, b'') 434 435 result = decode.FormatString('%li').format(encode.encode_args(-10)) 436 self.assertTrue(result.ok()) 437 self.assertEqual(result.value, '-10') 438 self.assertEqual(result.remaining, b'') 439 440 result = decode.FormatString('%lli').format(encode.encode_args(-10)) 441 self.assertTrue(result.ok()) 442 self.assertEqual(result.value, '-10') 443 self.assertEqual(result.remaining, b'') 444 445 result = decode.FormatString('%ji').format(encode.encode_args(-10)) 446 self.assertTrue(result.ok()) 447 self.assertEqual(result.value, '-10') 448 self.assertEqual(result.remaining, b'') 449 450 result = decode.FormatString('%zi').format(encode.encode_args(-10)) 451 self.assertTrue(result.ok()) 452 self.assertEqual(result.value, '-10') 453 self.assertEqual(result.remaining, b'') 454 455 result = decode.FormatString('%ti').format(encode.encode_args(-10)) 456 self.assertTrue(result.ok()) 457 self.assertEqual(result.value, '-10') 458 self.assertEqual(result.remaining, b'') 459 460 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 461 462 def test_unsigned_integer(self) -> None: 463 result = decode.FormatString('%u').format(encode.encode_args(10)) 464 self.assertTrue(result.ok()) 465 self.assertEqual(result.value, '10') 466 self.assertEqual(result.remaining, b'') 467 468 def test_unsigned_integer_with_hashtag(self) -> None: 469 result = decode.FormatString('%#u').format(encode.encode_args(10)) 470 self.assertFalse(result.ok()) 471 472 def test_unsigned_integer_with_length(self) -> None: 473 """Tests that length modifiers pass unsigned integer decoding.""" 474 result = decode.FormatString('%hhu').format(encode.encode_args(10)) 475 self.assertTrue(result.ok()) 476 self.assertEqual(result.value, '10') 477 self.assertEqual(result.remaining, b'') 478 479 result = decode.FormatString('%hu').format(encode.encode_args(10)) 480 self.assertTrue(result.ok()) 481 self.assertEqual(result.value, '10') 482 self.assertEqual(result.remaining, b'') 483 484 result = decode.FormatString('%lu').format(encode.encode_args(10)) 485 self.assertTrue(result.ok()) 486 self.assertEqual(result.value, '10') 487 self.assertEqual(result.remaining, b'') 488 489 result = decode.FormatString('%llu').format(encode.encode_args(10)) 490 self.assertTrue(result.ok()) 491 self.assertEqual(result.value, '10') 492 self.assertEqual(result.remaining, b'') 493 494 result = decode.FormatString('%ju').format(encode.encode_args(10)) 495 self.assertTrue(result.ok()) 496 self.assertEqual(result.value, '10') 497 self.assertEqual(result.remaining, b'') 498 499 result = decode.FormatString('%zu').format(encode.encode_args(10)) 500 self.assertTrue(result.ok()) 501 self.assertEqual(result.value, '10') 502 self.assertEqual(result.remaining, b'') 503 504 result = decode.FormatString('%tu').format(encode.encode_args(10)) 505 self.assertTrue(result.ok()) 506 self.assertEqual(result.value, '10') 507 self.assertEqual(result.remaining, b'') 508 509 result = decode.FormatString('%Lu').format(encode.encode_args(10)) 510 self.assertTrue(result.ok()) 511 self.assertEqual(result.value, '10') 512 self.assertEqual(result.remaining, b'') 513 514 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 515 516 def test_octal_integer(self) -> None: 517 result = decode.FormatString('%o').format(encode.encode_args(10)) 518 self.assertTrue(result.ok()) 519 self.assertEqual(result.value, '12') 520 self.assertEqual(result.remaining, b'') 521 522 def test_octal_integer_with_hashtag(self) -> None: 523 result = decode.FormatString('%#o').format(encode.encode_args(10)) 524 self.assertTrue(result.ok()) 525 self.assertEqual(result.value, '012') 526 self.assertEqual(result.remaining, b'') 527 528 def test_octal_integer_with_hashtag_and_width(self) -> None: 529 result = decode.FormatString('%#10o').format(encode.encode_args(10)) 530 self.assertTrue(result.ok()) 531 self.assertEqual(result.value, ' 012') 532 self.assertEqual(result.remaining, b'') 533 534 def test_octal_integer_with_hashtag_and_zero_and_width(self) -> None: 535 result = decode.FormatString('%#010o').format(encode.encode_args(10)) 536 self.assertTrue(result.ok()) 537 self.assertEqual(result.value, '0000000012') 538 self.assertEqual(result.remaining, b'') 539 540 def test_octal_integer_with_minus_and_hashtag(self) -> None: 541 result = decode.FormatString('%#-5o').format(encode.encode_args(10)) 542 self.assertTrue(result.ok()) 543 self.assertEqual(result.value, '012 ') 544 self.assertEqual(result.remaining, b'') 545 546 def test_octal_integer_with_plus_and_hashtag(self) -> None: 547 result = decode.FormatString('%+#o').format(encode.encode_args(10)) 548 self.assertTrue(result.ok()) 549 self.assertEqual(result.value, '+012') 550 self.assertEqual(result.remaining, b'') 551 552 def test_octal_integer_with_space_and_hashtag(self) -> None: 553 result = decode.FormatString('% #o').format(encode.encode_args(10)) 554 self.assertTrue(result.ok()) 555 self.assertEqual(result.value, ' 012') 556 self.assertEqual(result.remaining, b'') 557 558 def test_octal_integer_with_zero_and_hashtag(self) -> None: 559 result = decode.FormatString('%#05o').format(encode.encode_args(10)) 560 self.assertTrue(result.ok()) 561 self.assertEqual(result.value, '00012') 562 self.assertEqual(result.remaining, b'') 563 564 def test_octal_integer_with_plus_and_space_and_hashtag_ignores_space( 565 self, 566 ) -> None: 567 result = decode.FormatString('%+ #o').format(encode.encode_args(10)) 568 self.assertTrue(result.ok()) 569 self.assertEqual(result.value, '+012') 570 self.assertEqual(result.remaining, b'') 571 572 def test_octal_integer_with_length(self) -> None: 573 """Tests that length modifiers do not affect octal integer decoding.""" 574 result = decode.FormatString('%hho').format(encode.encode_args(10)) 575 self.assertTrue(result.ok()) 576 self.assertEqual(result.value, '12') 577 self.assertEqual(result.remaining, b'') 578 579 result = decode.FormatString('%ho').format(encode.encode_args(10)) 580 self.assertTrue(result.ok()) 581 self.assertEqual(result.value, '12') 582 self.assertEqual(result.remaining, b'') 583 584 result = decode.FormatString('%lo').format(encode.encode_args(10)) 585 self.assertTrue(result.ok()) 586 self.assertEqual(result.value, '12') 587 self.assertEqual(result.remaining, b'') 588 589 result = decode.FormatString('%llo').format(encode.encode_args(10)) 590 self.assertTrue(result.ok()) 591 self.assertEqual(result.value, '12') 592 self.assertEqual(result.remaining, b'') 593 594 result = decode.FormatString('%jo').format(encode.encode_args(10)) 595 self.assertTrue(result.ok()) 596 self.assertEqual(result.value, '12') 597 self.assertEqual(result.remaining, b'') 598 599 result = decode.FormatString('%zo').format(encode.encode_args(10)) 600 self.assertTrue(result.ok()) 601 self.assertEqual(result.value, '12') 602 self.assertEqual(result.remaining, b'') 603 604 result = decode.FormatString('%to').format(encode.encode_args(10)) 605 self.assertTrue(result.ok()) 606 self.assertEqual(result.value, '12') 607 self.assertEqual(result.remaining, b'') 608 609 result = decode.FormatString('%Lo').format(encode.encode_args(10)) 610 self.assertTrue(result.ok()) 611 self.assertEqual(result.value, '12') 612 self.assertEqual(result.remaining, b'') 613 614 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 615 616 def test_lowercase_hex_integer(self) -> None: 617 result = decode.FormatString('%x').format(encode.encode_args(10)) 618 self.assertTrue(result.ok()) 619 self.assertEqual(result.value, 'a') 620 self.assertEqual(result.remaining, b'') 621 622 def test_lowercase_hex_integer_with_hashtag(self) -> None: 623 result = decode.FormatString('%#x').format(encode.encode_args(10)) 624 self.assertTrue(result.ok()) 625 self.assertEqual(result.value, '0xa') 626 self.assertEqual(result.remaining, b'') 627 628 def test_lowercase_hex_integer_with_length(self) -> None: 629 """Tests that length modifiers do not affect lowercase hex decoding.""" 630 result = decode.FormatString('%hhx').format(encode.encode_args(10)) 631 self.assertTrue(result.ok()) 632 self.assertEqual(result.value, 'a') 633 self.assertEqual(result.remaining, b'') 634 635 result = decode.FormatString('%hx').format(encode.encode_args(10)) 636 self.assertTrue(result.ok()) 637 self.assertEqual(result.value, 'a') 638 self.assertEqual(result.remaining, b'') 639 640 result = decode.FormatString('%lx').format(encode.encode_args(10)) 641 self.assertTrue(result.ok()) 642 self.assertEqual(result.value, 'a') 643 self.assertEqual(result.remaining, b'') 644 645 result = decode.FormatString('%llx').format(encode.encode_args(10)) 646 self.assertTrue(result.ok()) 647 self.assertEqual(result.value, 'a') 648 self.assertEqual(result.remaining, b'') 649 650 result = decode.FormatString('%jx').format(encode.encode_args(10)) 651 self.assertTrue(result.ok()) 652 self.assertEqual(result.value, 'a') 653 self.assertEqual(result.remaining, b'') 654 655 result = decode.FormatString('%zx').format(encode.encode_args(10)) 656 self.assertTrue(result.ok()) 657 self.assertEqual(result.value, 'a') 658 self.assertEqual(result.remaining, b'') 659 660 result = decode.FormatString('%tx').format(encode.encode_args(10)) 661 self.assertTrue(result.ok()) 662 self.assertEqual(result.value, 'a') 663 self.assertEqual(result.remaining, b'') 664 665 result = decode.FormatString('%Lx').format(encode.encode_args(10)) 666 self.assertTrue(result.ok()) 667 self.assertEqual(result.value, 'a') 668 self.assertEqual(result.remaining, b'') 669 670 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 671 672 def test_uppercase_hex_integer(self) -> None: 673 result = decode.FormatString('%X').format(encode.encode_args(10)) 674 self.assertTrue(result.ok()) 675 self.assertEqual(result.value, 'A') 676 self.assertEqual(result.remaining, b'') 677 678 def test_uppercase_hex_integer_with_hashtag(self) -> None: 679 result = decode.FormatString('%#X').format(encode.encode_args(10)) 680 self.assertTrue(result.ok()) 681 self.assertEqual(result.value, '0XA') 682 self.assertEqual(result.remaining, b'') 683 684 def test_uppercase_hex_integer_with_length(self) -> None: 685 """Tests that length modifiers do not affect uppercase hex decoding.""" 686 result = decode.FormatString('%hhX').format(encode.encode_args(10)) 687 self.assertTrue(result.ok()) 688 self.assertEqual(result.value, 'A') 689 self.assertEqual(result.remaining, b'') 690 691 result = decode.FormatString('%hX').format(encode.encode_args(10)) 692 self.assertTrue(result.ok()) 693 self.assertEqual(result.value, 'A') 694 self.assertEqual(result.remaining, b'') 695 696 result = decode.FormatString('%lX').format(encode.encode_args(10)) 697 self.assertTrue(result.ok()) 698 self.assertEqual(result.value, 'A') 699 self.assertEqual(result.remaining, b'') 700 701 result = decode.FormatString('%llX').format(encode.encode_args(10)) 702 self.assertTrue(result.ok()) 703 self.assertEqual(result.value, 'A') 704 self.assertEqual(result.remaining, b'') 705 706 result = decode.FormatString('%jX').format(encode.encode_args(10)) 707 self.assertTrue(result.ok()) 708 self.assertEqual(result.value, 'A') 709 self.assertEqual(result.remaining, b'') 710 711 result = decode.FormatString('%zX').format(encode.encode_args(10)) 712 self.assertTrue(result.ok()) 713 self.assertEqual(result.value, 'A') 714 self.assertEqual(result.remaining, b'') 715 716 result = decode.FormatString('%tX').format(encode.encode_args(10)) 717 self.assertTrue(result.ok()) 718 self.assertEqual(result.value, 'A') 719 self.assertEqual(result.remaining, b'') 720 721 result = decode.FormatString('%LX').format(encode.encode_args(10)) 722 self.assertTrue(result.ok()) 723 self.assertEqual(result.value, 'A') 724 self.assertEqual(result.remaining, b'') 725 726 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 727 728 def test_decode_generated_data(self) -> None: 729 test_data = varint_test_data.TEST_DATA 730 self.assertGreater(len(test_data), 100) 731 732 for signed_spec, signed, unsigned_spec, unsigned, encoded in test_data: 733 self.assertEqual( 734 int(signed), 735 decode.FormatSpec.from_string(signed_spec) 736 .decode(bytearray(encoded)) 737 .value, 738 ) 739 740 self.assertEqual( 741 int(unsigned), 742 decode.FormatSpec.from_string(unsigned_spec) 743 .decode(bytearray(encoded)) 744 .value, 745 ) 746 747 748# pylint: disable=too-many-public-methods 749class TestFloatDecoding(unittest.TestCase): 750 """Tests decoding floating-point values using f or F.""" 751 752 def test_lowercase_float(self) -> None: 753 result = decode.FormatString('%f').format(encode.encode_args(2.2)) 754 self.assertTrue(result.ok()) 755 self.assertEqual(result.value, '2.200000') 756 self.assertEqual(result.remaining, b'') 757 758 def test_lowercase_float_with_minus(self) -> None: 759 result = decode.FormatString('%-10f').format(encode.encode_args(2.2)) 760 self.assertTrue(result.ok()) 761 self.assertEqual(result.value, '2.200000 ') 762 self.assertEqual(result.remaining, b'') 763 764 def test_lowercase_float_with_plus(self) -> None: 765 result = decode.FormatString('%+f').format(encode.encode_args(2.2)) 766 self.assertTrue(result.ok()) 767 self.assertEqual(result.value, '+2.200000') 768 self.assertEqual(result.remaining, b'') 769 770 def test_lowercase_float_with_blank_space(self) -> None: 771 result = decode.FormatString('% f').format(encode.encode_args(2.2)) 772 self.assertTrue(result.ok()) 773 self.assertEqual(result.value, ' 2.200000') 774 self.assertEqual(result.remaining, b'') 775 776 def test_lowercase_float_with_plus_and_blank_space_ignores_blank_space( 777 self, 778 ) -> None: 779 result = decode.FormatString('%+ f').format(encode.encode_args(2.2)) 780 self.assertTrue(result.ok()) 781 self.assertEqual(result.value, '+2.200000') 782 self.assertEqual(result.remaining, b'') 783 784 result = decode.FormatString('% +f').format(encode.encode_args(2.2)) 785 self.assertTrue(result.ok()) 786 self.assertEqual(result.value, '+2.200000') 787 self.assertEqual(result.remaining, b'') 788 789 def test_lowercase_float_with_hashtag(self) -> None: 790 result = decode.FormatString('%.0f').format(encode.encode_args(2.0)) 791 self.assertTrue(result.ok()) 792 self.assertEqual(result.value, '2') 793 self.assertEqual(result.remaining, b'') 794 795 result = decode.FormatString('%#.0f').format(encode.encode_args(2.0)) 796 self.assertTrue(result.ok()) 797 self.assertEqual(result.value, '2.') 798 self.assertEqual(result.remaining, b'') 799 800 def test_lowercase_float_with_zero(self) -> None: 801 result = decode.FormatString('%010f').format(encode.encode_args(2.2)) 802 self.assertTrue(result.ok()) 803 self.assertEqual(result.value, '002.200000') 804 self.assertEqual(result.remaining, b'') 805 806 def test_lowercase_float_with_length(self) -> None: 807 """Tests that length modifiers do not affect f decoding.""" 808 result = decode.FormatString('%hhf').format(encode.encode_args(2.2)) 809 self.assertTrue(result.ok()) 810 self.assertEqual(result.value, '2.200000') 811 self.assertEqual(result.remaining, b'') 812 813 result = decode.FormatString('%hf').format(encode.encode_args(2.2)) 814 self.assertTrue(result.ok()) 815 self.assertEqual(result.value, '2.200000') 816 self.assertEqual(result.remaining, b'') 817 818 result = decode.FormatString('%lf').format(encode.encode_args(2.2)) 819 self.assertTrue(result.ok()) 820 self.assertEqual(result.value, '2.200000') 821 self.assertEqual(result.remaining, b'') 822 823 result = decode.FormatString('%llf').format(encode.encode_args(2.2)) 824 self.assertTrue(result.ok()) 825 self.assertEqual(result.value, '2.200000') 826 self.assertEqual(result.remaining, b'') 827 828 result = decode.FormatString('%jf').format(encode.encode_args(2.2)) 829 self.assertTrue(result.ok()) 830 self.assertEqual(result.value, '2.200000') 831 self.assertEqual(result.remaining, b'') 832 833 result = decode.FormatString('%zf').format(encode.encode_args(2.2)) 834 self.assertTrue(result.ok()) 835 self.assertEqual(result.value, '2.200000') 836 self.assertEqual(result.remaining, b'') 837 838 result = decode.FormatString('%tf').format(encode.encode_args(2.2)) 839 self.assertTrue(result.ok()) 840 self.assertEqual(result.value, '2.200000') 841 self.assertEqual(result.remaining, b'') 842 843 result = decode.FormatString('%Lf').format(encode.encode_args(2.2)) 844 self.assertTrue(result.ok()) 845 self.assertEqual(result.value, '2.200000') 846 self.assertEqual(result.remaining, b'') 847 848 def test_lowercase_float_with_width(self) -> None: 849 result = decode.FormatString('%9f').format(encode.encode_args(2.2)) 850 self.assertTrue(result.ok()) 851 self.assertEqual(result.value, ' 2.200000') 852 853 def test_lowercase_float_with_multidigit_width(self) -> None: 854 result = decode.FormatString('%10f').format(encode.encode_args(2.2)) 855 self.assertTrue(result.ok()) 856 self.assertEqual(result.value, ' 2.200000') 857 858 def test_lowercase_float_with_star_width(self) -> None: 859 result = decode.FormatString('%*f').format(encode.encode_args(10, 2.2)) 860 self.assertTrue(result.ok()) 861 self.assertEqual(result.value, ' 2.200000') 862 863 def test_lowercase_float_non_number(self) -> None: 864 result = decode.FormatString('%f').format(encode.encode_args(math.inf)) 865 self.assertTrue(result.ok()) 866 self.assertEqual(result.value, 'inf') 867 self.assertEqual(result.remaining, b'') 868 869 def test_lowercase_float_with_precision(self) -> None: 870 result = decode.FormatString('%.4f').format(encode.encode_args(2.2)) 871 self.assertTrue(result.ok()) 872 self.assertEqual(result.value, '2.2000') 873 874 def test_lowercase_float_with_multidigit_precision(self) -> None: 875 result = decode.FormatString('%.10f').format(encode.encode_args(2.2)) 876 self.assertTrue(result.ok()) 877 self.assertEqual(result.value, '2.2000000477') 878 879 def test_lowercase_float_with_star_preision(self) -> None: 880 result = decode.FormatString('%.*f').format(encode.encode_args(10, 2.2)) 881 self.assertTrue(result.ok()) 882 self.assertEqual(result.value, '2.2000000477') 883 884 def test_lowercase_float_with_zero_precision(self) -> None: 885 result = decode.FormatString('%.0f').format(encode.encode_args(2.2)) 886 self.assertTrue(result.ok()) 887 self.assertEqual(result.value, '2') 888 889 def test_lowercase_float_with_empty_precision(self) -> None: 890 result = decode.FormatString('%.f').format(encode.encode_args(2.2)) 891 self.assertTrue(result.ok()) 892 self.assertEqual(result.value, '2') 893 894 def test_lowercase_float_with_width_and_precision(self) -> None: 895 result = decode.FormatString('%10.0f').format(encode.encode_args(2.2)) 896 self.assertTrue(result.ok()) 897 self.assertEqual(result.value, ' 2') 898 899 def test_lowercase_float_with_star_width_and_star_precision(self) -> None: 900 result = decode.FormatString('%*.*f').format( 901 encode.encode_args(20, 10, 2.2) 902 ) 903 self.assertTrue(result.ok()) 904 self.assertEqual(result.value, ' 2.2000000477') 905 906 def test_lowercase_float_non_number_with_minus(self) -> None: 907 result = decode.FormatString('%-5f').format( 908 encode.encode_args(math.inf) 909 ) 910 self.assertTrue(result.ok()) 911 self.assertEqual(result.value, 'inf ') 912 self.assertEqual(result.remaining, b'') 913 914 def test_lowercase_float_non_number_with_plus(self) -> None: 915 result = decode.FormatString('%+f').format(encode.encode_args(math.inf)) 916 self.assertTrue(result.ok()) 917 self.assertEqual(result.value, '+inf') 918 self.assertEqual(result.remaining, b'') 919 920 def test_lowercase_float_non_number_with_blank_space(self) -> None: 921 result = decode.FormatString('% f').format(encode.encode_args(math.inf)) 922 self.assertTrue(result.ok()) 923 self.assertEqual(result.value, ' inf') 924 self.assertEqual(result.remaining, b'') 925 926 def test_lowercase_float_non_number_with_plus_and_blank_ignores_blank( 927 self, 928 ) -> None: 929 result = decode.FormatString('%+ f').format( 930 encode.encode_args(math.inf) 931 ) 932 self.assertTrue(result.ok()) 933 self.assertEqual(result.value, '+inf') 934 self.assertEqual(result.remaining, b'') 935 936 result = decode.FormatString('% +f').format( 937 encode.encode_args(math.inf) 938 ) 939 self.assertTrue(result.ok()) 940 self.assertEqual(result.value, '+inf') 941 self.assertEqual(result.remaining, b'') 942 943 def test_lowercase_float_non_number_with_hashtag(self) -> None: 944 result = decode.FormatString('%#f').format(encode.encode_args(math.inf)) 945 self.assertTrue(result.ok()) 946 self.assertEqual(result.value, 'inf') 947 self.assertEqual(result.remaining, b'') 948 949 def test_lowercase_float_non_number_zero(self) -> None: 950 result = decode.FormatString('%05f').format( 951 encode.encode_args(math.inf) 952 ) 953 self.assertTrue(result.ok()) 954 self.assertEqual(result.value, ' inf') 955 self.assertEqual(result.remaining, b'') 956 957 def test_lowercase_float_non_number_with_width(self) -> None: 958 result = decode.FormatString('%9f').format(encode.encode_args(math.inf)) 959 self.assertTrue(result.ok()) 960 self.assertEqual(result.value, ' inf') 961 962 def test_lowercase_float_non_number_with_multidigit_width(self) -> None: 963 result = decode.FormatString('%10f').format( 964 encode.encode_args(math.inf) 965 ) 966 self.assertTrue(result.ok()) 967 self.assertEqual(result.value, ' inf') 968 969 def test_lowercase_float_non_number_with_star_width(self) -> None: 970 result = decode.FormatString('%*f').format( 971 encode.encode_args(10, math.inf) 972 ) 973 self.assertTrue(result.ok()) 974 self.assertEqual(result.value, ' inf') 975 976 def test_lowercase_float_non_number_with_precision(self) -> None: 977 result = decode.FormatString('%.4f').format( 978 encode.encode_args(math.inf) 979 ) 980 self.assertTrue(result.ok()) 981 self.assertEqual(result.value, 'inf') 982 983 def test_lowercase_float_non_number_with_multidigit_precision(self) -> None: 984 result = decode.FormatString('%.10f').format( 985 encode.encode_args(math.inf) 986 ) 987 self.assertTrue(result.ok()) 988 self.assertEqual(result.value, 'inf') 989 990 def test_lowercase_float_non_number_with_star_preision(self) -> None: 991 result = decode.FormatString('%.*f').format( 992 encode.encode_args(10, math.inf) 993 ) 994 self.assertTrue(result.ok()) 995 self.assertEqual(result.value, 'inf') 996 997 def test_lowercase_float_non_number_with_zero_precision(self) -> None: 998 result = decode.FormatString('%.0f').format( 999 encode.encode_args(math.inf) 1000 ) 1001 self.assertTrue(result.ok()) 1002 self.assertEqual(result.value, 'inf') 1003 1004 def test_lowercase_float_non_number_with_empty_precision(self) -> None: 1005 result = decode.FormatString('%.f').format(encode.encode_args(math.inf)) 1006 self.assertTrue(result.ok()) 1007 self.assertEqual(result.value, 'inf') 1008 1009 def test_lowercase_float_non_number_with_width_and_precision(self) -> None: 1010 result = decode.FormatString('%10.0f').format( 1011 encode.encode_args(math.inf) 1012 ) 1013 self.assertTrue(result.ok()) 1014 self.assertEqual(result.value, ' inf') 1015 1016 def test_lowercase_float_non_number_with_star_width_and_star_precision( 1017 self, 1018 ) -> None: 1019 result = decode.FormatString('%*.*f').format( 1020 encode.encode_args(10, 0, math.inf) 1021 ) 1022 self.assertTrue(result.ok()) 1023 self.assertEqual(result.value, ' inf') 1024 1025 def test_zero_with_zero_precision(self) -> None: 1026 result = decode.FormatString('%.0f').format(encode.encode_args(0.0)) 1027 self.assertTrue(result.ok()) 1028 self.assertEqual(result.value, '0') 1029 1030 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 1031 1032 def test_uppercase_float(self) -> None: 1033 result = decode.FormatString('%F').format(encode.encode_args(2.2)) 1034 self.assertTrue(result.ok()) 1035 self.assertEqual(result.value, '2.200000') 1036 self.assertEqual(result.remaining, b'') 1037 1038 def test_uppercase_float_with_length(self) -> None: 1039 """Tests that length modifiers do not affect F decoding.""" 1040 result = decode.FormatString('%hhF').format(encode.encode_args(2.2)) 1041 self.assertTrue(result.ok()) 1042 self.assertEqual(result.value, '2.200000') 1043 self.assertEqual(result.remaining, b'') 1044 1045 result = decode.FormatString('%hF').format(encode.encode_args(2.2)) 1046 self.assertTrue(result.ok()) 1047 self.assertEqual(result.value, '2.200000') 1048 self.assertEqual(result.remaining, b'') 1049 1050 result = decode.FormatString('%lF').format(encode.encode_args(2.2)) 1051 self.assertTrue(result.ok()) 1052 self.assertEqual(result.value, '2.200000') 1053 self.assertEqual(result.remaining, b'') 1054 1055 result = decode.FormatString('%llF').format(encode.encode_args(2.2)) 1056 self.assertTrue(result.ok()) 1057 self.assertEqual(result.value, '2.200000') 1058 self.assertEqual(result.remaining, b'') 1059 1060 result = decode.FormatString('%jF').format(encode.encode_args(2.2)) 1061 self.assertTrue(result.ok()) 1062 self.assertEqual(result.value, '2.200000') 1063 self.assertEqual(result.remaining, b'') 1064 1065 result = decode.FormatString('%zF').format(encode.encode_args(2.2)) 1066 self.assertTrue(result.ok()) 1067 self.assertEqual(result.value, '2.200000') 1068 1069 result = decode.FormatString('%tF').format(encode.encode_args(2.2)) 1070 self.assertTrue(result.ok()) 1071 self.assertEqual(result.value, '2.200000') 1072 self.assertEqual(result.remaining, b'') 1073 self.assertEqual(result.remaining, b'') 1074 1075 result = decode.FormatString('%LF').format(encode.encode_args(2.2)) 1076 self.assertTrue(result.ok()) 1077 self.assertEqual(result.value, '2.200000') 1078 self.assertEqual(result.remaining, b'') 1079 1080 def test_uppercase_float_non_number(self) -> None: 1081 result = decode.FormatString('%F').format(encode.encode_args(math.inf)) 1082 self.assertTrue(result.ok()) 1083 self.assertEqual(result.value, 'INF') 1084 self.assertEqual(result.remaining, b'') 1085 1086 def test_lowercase_exponential(self) -> None: 1087 result = decode.FormatString('%e').format(encode.encode_args(2.2)) 1088 self.assertTrue(result.ok()) 1089 self.assertEqual(result.value, '2.200000e+00') 1090 self.assertEqual(result.remaining, b'') 1091 1092 def test_lowercase_exponential_with_length(self) -> None: 1093 """Tests that length modifiers do not affect e decoding.""" 1094 result = decode.FormatString('%hhe').format(encode.encode_args(2.2)) 1095 self.assertTrue(result.ok()) 1096 self.assertEqual(result.value, '2.200000e+00') 1097 self.assertEqual(result.remaining, b'') 1098 1099 # inclusive-language: disable 1100 result = decode.FormatString('%he').format(encode.encode_args(2.2)) 1101 # inclusive-language: enable 1102 self.assertTrue(result.ok()) 1103 self.assertEqual(result.value, '2.200000e+00') 1104 self.assertEqual(result.remaining, b'') 1105 1106 result = decode.FormatString('%le').format(encode.encode_args(2.2)) 1107 self.assertTrue(result.ok()) 1108 self.assertEqual(result.value, '2.200000e+00') 1109 self.assertEqual(result.remaining, b'') 1110 1111 result = decode.FormatString('%lle').format(encode.encode_args(2.2)) 1112 self.assertTrue(result.ok()) 1113 self.assertEqual(result.value, '2.200000e+00') 1114 self.assertEqual(result.remaining, b'') 1115 1116 result = decode.FormatString('%je').format(encode.encode_args(2.2)) 1117 self.assertTrue(result.ok()) 1118 self.assertEqual(result.value, '2.200000e+00') 1119 self.assertEqual(result.remaining, b'') 1120 1121 result = decode.FormatString('%ze').format(encode.encode_args(2.2)) 1122 self.assertTrue(result.ok()) 1123 self.assertEqual(result.value, '2.200000e+00') 1124 self.assertEqual(result.remaining, b'') 1125 1126 result = decode.FormatString('%te').format(encode.encode_args(2.2)) 1127 self.assertTrue(result.ok()) 1128 self.assertEqual(result.value, '2.200000e+00') 1129 self.assertEqual(result.remaining, b'') 1130 1131 result = decode.FormatString('%Le').format(encode.encode_args(2.2)) 1132 self.assertTrue(result.ok()) 1133 self.assertEqual(result.value, '2.200000e+00') 1134 self.assertEqual(result.remaining, b'') 1135 1136 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 1137 1138 def test_uppercase_exponential(self) -> None: 1139 result = decode.FormatString('%E').format(encode.encode_args(2.2)) 1140 self.assertTrue(result.ok()) 1141 self.assertEqual(result.value, '2.200000E+00') 1142 self.assertEqual(result.remaining, b'') 1143 1144 def test_uppercase_exponential_with_length(self) -> None: 1145 """Tests that length modifiers do not affect E decoding.""" 1146 result = decode.FormatString('%hhE').format(encode.encode_args(2.2)) 1147 self.assertTrue(result.ok()) 1148 self.assertEqual(result.value, '2.200000E+00') 1149 self.assertEqual(result.remaining, b'') 1150 1151 # inclusive-language: disable 1152 result = decode.FormatString('%hE').format(encode.encode_args(2.2)) 1153 # inclusive-language: enable 1154 self.assertTrue(result.ok()) 1155 self.assertEqual(result.value, '2.200000E+00') 1156 self.assertEqual(result.remaining, b'') 1157 1158 result = decode.FormatString('%lE').format(encode.encode_args(2.2)) 1159 self.assertTrue(result.ok()) 1160 self.assertEqual(result.value, '2.200000E+00') 1161 self.assertEqual(result.remaining, b'') 1162 1163 result = decode.FormatString('%llE').format(encode.encode_args(2.2)) 1164 self.assertTrue(result.ok()) 1165 self.assertEqual(result.value, '2.200000E+00') 1166 self.assertEqual(result.remaining, b'') 1167 1168 result = decode.FormatString('%jE').format(encode.encode_args(2.2)) 1169 self.assertTrue(result.ok()) 1170 self.assertEqual(result.value, '2.200000E+00') 1171 self.assertEqual(result.remaining, b'') 1172 1173 result = decode.FormatString('%zE').format(encode.encode_args(2.2)) 1174 self.assertTrue(result.ok()) 1175 self.assertEqual(result.value, '2.200000E+00') 1176 self.assertEqual(result.remaining, b'') 1177 1178 result = decode.FormatString('%tE').format(encode.encode_args(2.2)) 1179 self.assertTrue(result.ok()) 1180 self.assertEqual(result.value, '2.200000E+00') 1181 self.assertEqual(result.remaining, b'') 1182 1183 result = decode.FormatString('%LE').format(encode.encode_args(2.2)) 1184 self.assertTrue(result.ok()) 1185 self.assertEqual(result.value, '2.200000E+00') 1186 self.assertEqual(result.remaining, b'') 1187 1188 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 1189 1190 def test_lowercase_shortest_take_normal(self) -> None: 1191 result = decode.FormatString('%g').format(encode.encode_args(2.2)) 1192 self.assertTrue(result.ok()) 1193 self.assertEqual(result.value, '2.2') 1194 self.assertEqual(result.remaining, b'') 1195 1196 def test_lowercase_shortest_take_exponential(self) -> None: 1197 result = decode.FormatString('%g').format(encode.encode_args(1048580.0)) 1198 self.assertTrue(result.ok()) 1199 self.assertEqual(result.value, '1.04858e+06') 1200 self.assertEqual(result.remaining, b'') 1201 1202 def test_lowercase_shortest_with_length(self) -> None: 1203 """Tests that length modifiers do not affect g decoding.""" 1204 result = decode.FormatString('%hhg').format(encode.encode_args(2.2)) 1205 self.assertTrue(result.ok()) 1206 self.assertEqual(result.value, '2.2') 1207 self.assertEqual(result.remaining, b'') 1208 1209 result = decode.FormatString('%hg').format(encode.encode_args(2.2)) 1210 self.assertTrue(result.ok()) 1211 self.assertEqual(result.value, '2.2') 1212 self.assertEqual(result.remaining, b'') 1213 1214 result = decode.FormatString('%lg').format(encode.encode_args(2.2)) 1215 self.assertTrue(result.ok()) 1216 self.assertEqual(result.value, '2.2') 1217 self.assertEqual(result.remaining, b'') 1218 1219 result = decode.FormatString('%llg').format(encode.encode_args(2.2)) 1220 self.assertTrue(result.ok()) 1221 self.assertEqual(result.value, '2.2') 1222 self.assertEqual(result.remaining, b'') 1223 1224 result = decode.FormatString('%jg').format(encode.encode_args(2.2)) 1225 self.assertTrue(result.ok()) 1226 self.assertEqual(result.value, '2.2') 1227 self.assertEqual(result.remaining, b'') 1228 1229 result = decode.FormatString('%zg').format(encode.encode_args(2.2)) 1230 self.assertTrue(result.ok()) 1231 self.assertEqual(result.value, '2.2') 1232 self.assertEqual(result.remaining, b'') 1233 1234 result = decode.FormatString('%tg').format(encode.encode_args(2.2)) 1235 self.assertTrue(result.ok()) 1236 self.assertEqual(result.value, '2.2') 1237 self.assertEqual(result.remaining, b'') 1238 1239 result = decode.FormatString('%Lg').format(encode.encode_args(2.2)) 1240 self.assertTrue(result.ok()) 1241 self.assertEqual(result.value, '2.2') 1242 self.assertEqual(result.remaining, b'') 1243 1244 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 1245 1246 def test_uppercase_shortest_take_normal(self) -> None: 1247 result = decode.FormatString('%G').format(encode.encode_args(2.2)) 1248 self.assertTrue(result.ok()) 1249 self.assertEqual(result.value, '2.2') 1250 self.assertEqual(result.remaining, b'') 1251 1252 def test_uppercase_shortest_take_exponential(self) -> None: 1253 result = decode.FormatString('%G').format(encode.encode_args(1048580.0)) 1254 self.assertTrue(result.ok()) 1255 self.assertEqual(result.value, '1.04858E+06') 1256 self.assertEqual(result.remaining, b'') 1257 1258 def test_uppercase_shortest_with_length(self) -> None: 1259 """Tests that length modifiers do not affect G decoding.""" 1260 result = decode.FormatString('%hhG').format(encode.encode_args(2.2)) 1261 self.assertTrue(result.ok()) 1262 self.assertEqual(result.value, '2.2') 1263 self.assertEqual(result.remaining, b'') 1264 1265 result = decode.FormatString('%hG').format(encode.encode_args(2.2)) 1266 self.assertTrue(result.ok()) 1267 self.assertEqual(result.value, '2.2') 1268 self.assertEqual(result.remaining, b'') 1269 1270 result = decode.FormatString('%lG').format(encode.encode_args(2.2)) 1271 self.assertTrue(result.ok()) 1272 self.assertEqual(result.value, '2.2') 1273 self.assertEqual(result.remaining, b'') 1274 1275 result = decode.FormatString('%llG').format(encode.encode_args(2.2)) 1276 self.assertTrue(result.ok()) 1277 self.assertEqual(result.value, '2.2') 1278 self.assertEqual(result.remaining, b'') 1279 1280 result = decode.FormatString('%jG').format(encode.encode_args(2.2)) 1281 self.assertTrue(result.ok()) 1282 self.assertEqual(result.value, '2.2') 1283 self.assertEqual(result.remaining, b'') 1284 1285 result = decode.FormatString('%zG').format(encode.encode_args(2.2)) 1286 self.assertTrue(result.ok()) 1287 self.assertEqual(result.value, '2.2') 1288 self.assertEqual(result.remaining, b'') 1289 1290 result = decode.FormatString('%tG').format(encode.encode_args(2.2)) 1291 self.assertTrue(result.ok()) 1292 self.assertEqual(result.value, '2.2') 1293 self.assertEqual(result.remaining, b'') 1294 1295 result = decode.FormatString('%LG').format(encode.encode_args(2.2)) 1296 self.assertTrue(result.ok()) 1297 self.assertEqual(result.value, '2.2') 1298 self.assertEqual(result.remaining, b'') 1299 1300 1301class TestCharDecoding(unittest.TestCase): 1302 """Tests decoding character values.""" 1303 1304 def test_char(self) -> None: 1305 result = decode.FormatString('%c').format(encode.encode_args(ord('c'))) 1306 self.assertTrue(result.ok()) 1307 self.assertEqual(result.value, 'c') 1308 self.assertEqual(result.remaining, b'') 1309 1310 def test_char_with_minus(self) -> None: 1311 result = decode.FormatString('%-5c').format( 1312 encode.encode_args(ord('c')) 1313 ) 1314 self.assertTrue(result.ok()) 1315 self.assertEqual(result.value, 'c ') 1316 self.assertEqual(result.remaining, b'') 1317 1318 def test_char_with_plus(self) -> None: 1319 result = decode.FormatString('%+c').format(encode.encode_args(ord('c'))) 1320 self.assertFalse(result.ok()) 1321 1322 def test_char_with_blank_space(self) -> None: 1323 result = decode.FormatString('% c').format(encode.encode_args(ord('c'))) 1324 self.assertFalse(result.ok()) 1325 1326 def test_char_with_hashtag(self) -> None: 1327 result = decode.FormatString('%#c').format(encode.encode_args(ord('c'))) 1328 self.assertFalse(result.ok()) 1329 1330 def test_char_with_zero(self) -> None: 1331 result = decode.FormatString('%0c').format(encode.encode_args(ord('c'))) 1332 self.assertFalse(result.ok()) 1333 1334 def test_char_with_length(self) -> None: 1335 """Tests that length modifiers do not affectchar decoding.""" 1336 result = decode.FormatString('%hhc').format( 1337 encode.encode_args(ord('c')) 1338 ) 1339 self.assertTrue(result.ok()) 1340 self.assertEqual(result.value, 'c') 1341 self.assertEqual(result.remaining, b'') 1342 1343 result = decode.FormatString('%hc').format(encode.encode_args(ord('c'))) 1344 self.assertTrue(result.ok()) 1345 self.assertEqual(result.value, 'c') 1346 self.assertEqual(result.remaining, b'') 1347 1348 result = decode.FormatString('%lc').format(encode.encode_args(ord('c'))) 1349 self.assertTrue(result.ok()) 1350 self.assertEqual(result.value, 'c') 1351 self.assertEqual(result.remaining, b'') 1352 1353 result = decode.FormatString('%llc').format( 1354 encode.encode_args(ord('c')) 1355 ) 1356 self.assertTrue(result.ok()) 1357 self.assertEqual(result.value, 'c') 1358 self.assertEqual(result.remaining, b'') 1359 1360 result = decode.FormatString('%jc').format(encode.encode_args(ord('c'))) 1361 self.assertTrue(result.ok()) 1362 self.assertEqual(result.value, 'c') 1363 self.assertEqual(result.remaining, b'') 1364 1365 result = decode.FormatString('%zc').format(encode.encode_args(ord('c'))) 1366 self.assertTrue(result.ok()) 1367 self.assertEqual(result.value, 'c') 1368 self.assertEqual(result.remaining, b'') 1369 1370 result = decode.FormatString('%tc').format(encode.encode_args(ord('c'))) 1371 self.assertTrue(result.ok()) 1372 self.assertEqual(result.value, 'c') 1373 self.assertEqual(result.remaining, b'') 1374 1375 result = decode.FormatString('%Lc').format(encode.encode_args(ord('c'))) 1376 self.assertTrue(result.ok()) 1377 self.assertEqual(result.value, 'c') 1378 self.assertEqual(result.remaining, b'') 1379 1380 def test_char_with_width(self) -> None: 1381 result = decode.FormatString('%5c').format(encode.encode_args(ord('c'))) 1382 self.assertTrue(result.ok()) 1383 self.assertEqual(result.value, ' c') 1384 1385 def test_char_with_multidigit_width(self) -> None: 1386 result = decode.FormatString('%10c').format( 1387 encode.encode_args(ord('c')) 1388 ) 1389 self.assertTrue(result.ok()) 1390 self.assertEqual(result.value, ' c') 1391 1392 def test_char_with_star_width(self) -> None: 1393 result = decode.FormatString('%*c').format( 1394 encode.encode_args(10, ord('c')) 1395 ) 1396 self.assertTrue(result.ok()) 1397 self.assertEqual(result.value, ' c') 1398 1399 def test_char_with_precision(self) -> None: 1400 result = decode.FormatString('%.4c').format( 1401 encode.encode_args(ord('c')) 1402 ) 1403 self.assertFalse(result.ok()) 1404 1405 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 1406 1407 def test_long_char(self) -> None: 1408 result = decode.FormatString('%lc').format(encode.encode_args(ord('c'))) 1409 self.assertTrue(result.ok()) 1410 self.assertEqual(result.value, 'c') 1411 self.assertEqual(result.remaining, b'') 1412 1413 def test_long_char_with_hashtag(self) -> None: 1414 result = decode.FormatString('%#lc').format( 1415 encode.encode_args(ord('c')) 1416 ) 1417 self.assertFalse(result.ok()) 1418 1419 def test_long_char_with_zero(self) -> None: 1420 result = decode.FormatString('%0lc').format( 1421 encode.encode_args(ord('c')) 1422 ) 1423 self.assertFalse(result.ok()) 1424 1425 1426class TestStringDecoding(unittest.TestCase): 1427 """Tests decoding string values.""" 1428 1429 def test_string(self) -> None: 1430 result = decode.FormatString('%s').format(encode.encode_args('hello')) 1431 self.assertTrue(result.ok()) 1432 self.assertEqual(result.value, 'hello') 1433 self.assertEqual(result.remaining, b'') 1434 1435 def test_string_with_minus(self) -> None: 1436 result = decode.FormatString('%-6s').format(encode.encode_args('hello')) 1437 self.assertTrue(result.ok()) 1438 self.assertEqual(result.value, 'hello ') 1439 self.assertEqual(result.remaining, b'') 1440 1441 def test_string_with_plus(self) -> None: 1442 result = decode.FormatString('%+s').format(encode.encode_args('hello')) 1443 self.assertFalse(result.ok()) 1444 1445 def test_string_with_blank_space(self) -> None: 1446 result = decode.FormatString('% s').format(encode.encode_args('hello')) 1447 self.assertFalse(result.ok()) 1448 1449 def test_string_with_hashtag(self) -> None: 1450 result = decode.FormatString('%#s').format(encode.encode_args('hello')) 1451 self.assertFalse(result.ok()) 1452 1453 def test_string_with_zero(self) -> None: 1454 result = decode.FormatString('%0s').format(encode.encode_args('hello')) 1455 self.assertFalse(result.ok()) 1456 1457 def test_string_with_length(self) -> None: 1458 """Tests that length modifiers do not affect string values (s).""" 1459 result = decode.FormatString('%hhs').format(encode.encode_args('hello')) 1460 self.assertTrue(result.ok()) 1461 self.assertEqual(result.value, 'hello') 1462 self.assertEqual(result.remaining, b'') 1463 1464 result = decode.FormatString('%hs').format(encode.encode_args('hello')) 1465 self.assertTrue(result.ok()) 1466 self.assertEqual(result.value, 'hello') 1467 self.assertEqual(result.remaining, b'') 1468 1469 result = decode.FormatString('%ls').format(encode.encode_args('hello')) 1470 self.assertTrue(result.ok()) 1471 self.assertEqual(result.value, 'hello') 1472 self.assertEqual(result.remaining, b'') 1473 1474 result = decode.FormatString('%lls').format(encode.encode_args('hello')) 1475 self.assertTrue(result.ok()) 1476 self.assertEqual(result.value, 'hello') 1477 self.assertEqual(result.remaining, b'') 1478 1479 result = decode.FormatString('%js').format(encode.encode_args('hello')) 1480 self.assertTrue(result.ok()) 1481 self.assertEqual(result.value, 'hello') 1482 self.assertEqual(result.remaining, b'') 1483 1484 result = decode.FormatString('%zs').format(encode.encode_args('hello')) 1485 self.assertTrue(result.ok()) 1486 self.assertEqual(result.value, 'hello') 1487 self.assertEqual(result.remaining, b'') 1488 1489 result = decode.FormatString('%ts').format(encode.encode_args('hello')) 1490 self.assertTrue(result.ok()) 1491 self.assertEqual(result.value, 'hello') 1492 self.assertEqual(result.remaining, b'') 1493 1494 result = decode.FormatString('%Ls').format(encode.encode_args('hello')) 1495 self.assertTrue(result.ok()) 1496 self.assertEqual(result.value, 'hello') 1497 self.assertEqual(result.remaining, b'') 1498 1499 def test_string_with_width(self) -> None: 1500 result = decode.FormatString('%6s').format(encode.encode_args('hello')) 1501 self.assertTrue(result.ok()) 1502 self.assertEqual(result.value, ' hello') 1503 1504 def test_string_with_width_does_not_pad_a_string_with_same_length( 1505 self, 1506 ) -> None: 1507 result = decode.FormatString('%5s').format(encode.encode_args('hello')) 1508 self.assertTrue(result.ok()) 1509 self.assertEqual(result.value, 'hello') 1510 1511 def test_string_with_multidigit_width(self) -> None: 1512 result = decode.FormatString('%10s').format(encode.encode_args('hello')) 1513 self.assertTrue(result.ok()) 1514 self.assertEqual(result.value, ' hello') 1515 1516 def test_string_with_star_width(self) -> None: 1517 result = decode.FormatString('%*s').format( 1518 encode.encode_args(10, 'hello') 1519 ) 1520 self.assertTrue(result.ok()) 1521 self.assertEqual(result.value, ' hello') 1522 1523 def test_string_with_precision(self) -> None: 1524 result = decode.FormatString('%.3s').format(encode.encode_args('hello')) 1525 self.assertTrue(result.ok()) 1526 self.assertEqual(result.value, 'hel') 1527 1528 def test_string_with_multidigit_precision(self) -> None: 1529 result = decode.FormatString('%.10s').format( 1530 encode.encode_args('hello') 1531 ) 1532 self.assertTrue(result.ok()) 1533 self.assertEqual(result.value, 'hello') 1534 1535 def test_string_with_star_precision(self) -> None: 1536 result = decode.FormatString('%.*s').format( 1537 encode.encode_args(3, 'hello') 1538 ) 1539 self.assertTrue(result.ok()) 1540 self.assertEqual(result.value, 'hel') 1541 1542 def test_string_with_width_and_precision(self) -> None: 1543 result = decode.FormatString('%10.3s').format( 1544 encode.encode_args('hello') 1545 ) 1546 self.assertTrue(result.ok()) 1547 self.assertEqual(result.value, ' hel') 1548 1549 def test_string_with_star_with_and_star_precision(self) -> None: 1550 result = decode.FormatString('%*.*s').format( 1551 encode.encode_args(10, 3, 'hello') 1552 ) 1553 self.assertTrue(result.ok()) 1554 self.assertEqual(result.value, ' hel') 1555 1556 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 1557 1558 def test_long_string(self) -> None: 1559 result = decode.FormatString('%ls').format(encode.encode_args('hello')) 1560 self.assertTrue(result.ok()) 1561 self.assertEqual(result.value, 'hello') 1562 self.assertEqual(result.remaining, b'') 1563 1564 def test_long_string_with_hashtag(self) -> None: 1565 result = decode.FormatString('%#ls').format(encode.encode_args('hello')) 1566 self.assertFalse(result.ok()) 1567 self.assertEqual(result.remaining, encode.encode_args('hello')) 1568 1569 def test_long_string_with_zero(self) -> None: 1570 result = decode.FormatString('%0ls').format(encode.encode_args('hello')) 1571 self.assertFalse(result.ok()) 1572 self.assertEqual(result.remaining, encode.encode_args('hello')) 1573 1574 1575class TestPointerDecoding(unittest.TestCase): 1576 """Tests decoding pointer values.""" 1577 1578 def test_pointer(self) -> None: 1579 result = decode.FormatString('%p').format( 1580 encode.encode_args(0xDEADBEEF) 1581 ) 1582 self.assertTrue(result.ok()) 1583 self.assertEqual(result.value, '0xDEADBEEF') 1584 self.assertEqual(result.remaining, b'') 1585 1586 def test_pointer_with_minus(self) -> None: 1587 result = decode.FormatString('%-12p').format( 1588 encode.encode_args(0xDEADBEEF) 1589 ) 1590 self.assertTrue(result.ok()) 1591 self.assertEqual(result.value, '0xDEADBEEF ') 1592 self.assertEqual(result.remaining, b'') 1593 1594 def test_pointer_with_plus(self) -> None: 1595 result = decode.FormatString('%+p').format( 1596 encode.encode_args(0xDEADBEEF) 1597 ) 1598 self.assertTrue(result.ok()) 1599 self.assertEqual(result.value, '+0xDEADBEEF') 1600 self.assertEqual(result.remaining, b'') 1601 1602 def test_pointer_with_blank_space(self) -> None: 1603 result = decode.FormatString('% p').format( 1604 encode.encode_args(0xDEADBEEF) 1605 ) 1606 self.assertTrue(result.ok()) 1607 self.assertEqual(result.value, ' 0xDEADBEEF') 1608 self.assertEqual(result.remaining, b'') 1609 1610 def test_pointer_with_hashtag(self) -> None: 1611 result = decode.FormatString('%#p').format( 1612 encode.encode_args(0xDEADBEEF) 1613 ) 1614 self.assertFalse(result.ok()) 1615 self.assertEqual(result.remaining, encode.encode_args(0xDEADBEEF)) 1616 1617 def test_pointer_with_zero(self) -> None: 1618 result = decode.FormatString('%0p').format( 1619 encode.encode_args(0xDEADBEEF) 1620 ) 1621 self.assertFalse(result.ok()) 1622 self.assertEqual(result.remaining, encode.encode_args(0xDEADBEEF)) 1623 1624 def test_pointer_with_length(self) -> None: 1625 """Tests that length modifiers do not affect decoding pointers (p).""" 1626 result = decode.FormatString('%hhp').format( 1627 encode.encode_args(0xDEADBEEF) 1628 ) 1629 self.assertFalse(result.ok()) 1630 self.assertEqual(result.remaining, encode.encode_args(0xDEADBEEF)) 1631 1632 result = decode.FormatString('%hp').format( 1633 encode.encode_args(0xDEADBEEF) 1634 ) 1635 self.assertFalse(result.ok()) 1636 self.assertEqual(result.remaining, encode.encode_args(0xDEADBEEF)) 1637 1638 result = decode.FormatString('%lp').format( 1639 encode.encode_args(0xDEADBEEF) 1640 ) 1641 self.assertFalse(result.ok()) 1642 self.assertEqual(result.remaining, encode.encode_args(0xDEADBEEF)) 1643 1644 result = decode.FormatString('%llp').format( 1645 encode.encode_args(0xDEADBEEF) 1646 ) 1647 self.assertFalse(result.ok()) 1648 self.assertEqual(result.remaining, encode.encode_args(0xDEADBEEF)) 1649 1650 result = decode.FormatString('%jp').format( 1651 encode.encode_args(0xDEADBEEF) 1652 ) 1653 self.assertFalse(result.ok()) 1654 self.assertEqual(result.remaining, encode.encode_args(0xDEADBEEF)) 1655 1656 result = decode.FormatString('%zp').format( 1657 encode.encode_args(0xDEADBEEF) 1658 ) 1659 self.assertFalse(result.ok()) 1660 self.assertEqual(result.remaining, encode.encode_args(0xDEADBEEF)) 1661 1662 result = decode.FormatString('%tp').format( 1663 encode.encode_args(0xDEADBEEF) 1664 ) 1665 self.assertFalse(result.ok()) 1666 self.assertEqual(result.remaining, encode.encode_args(0xDEADBEEF)) 1667 1668 result = decode.FormatString('%Lp').format( 1669 encode.encode_args(0xDEADBEEF) 1670 ) 1671 self.assertFalse(result.ok()) 1672 self.assertEqual(result.remaining, encode.encode_args(0xDEADBEEF)) 1673 1674 def test_pointer_with_width(self) -> None: 1675 result = decode.FormatString('%9p').format( 1676 encode.encode_args(0xDEADBEEF) 1677 ) 1678 self.assertTrue(result.ok()) 1679 self.assertEqual(result.value, '0xDEADBEEF') 1680 self.assertEqual(result.remaining, b'') 1681 1682 def test_pointer_with_multidigit_width(self) -> None: 1683 result = decode.FormatString('%11p').format( 1684 encode.encode_args(0xDEADBEEF) 1685 ) 1686 self.assertTrue(result.ok()) 1687 self.assertEqual(result.value, ' 0xDEADBEEF') 1688 self.assertEqual(result.remaining, b'') 1689 1690 def test_pointer_with_star_width(self) -> None: 1691 result = decode.FormatString('%*p').format( 1692 encode.encode_args(10, 0xDEADBEEF) 1693 ) 1694 self.assertTrue(result.ok()) 1695 self.assertEqual(result.value, '0xDEADBEEF') 1696 self.assertEqual(result.remaining, b'') 1697 1698 result = decode.FormatString('%*p').format( 1699 encode.encode_args(15, 0xDEADBEEF) 1700 ) 1701 self.assertTrue(result.ok()) 1702 self.assertEqual(result.value, ' 0xDEADBEEF') 1703 self.assertEqual(result.remaining, b'') 1704 1705 def test_pointer_with_precision(self) -> None: 1706 result = decode.FormatString('%.10p').format( 1707 encode.encode_args(0xDEADBEEF) 1708 ) 1709 self.assertFalse(result.ok()) 1710 self.assertEqual(result.remaining, encode.encode_args(0xDEADBEEF)) 1711 1712 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 1713 1714 def test_pointer_0_padding(self) -> None: 1715 result = decode.FormatString('%p').format( 1716 encode.encode_args(0x00000000) 1717 ) 1718 self.assertTrue(result.ok()) 1719 self.assertEqual(result.value, '0x00000000') 1720 self.assertEqual(result.remaining, b'') 1721 1722 def test_pointer_0_with_width(self) -> None: 1723 result = decode.FormatString('%9p').format( 1724 encode.encode_args(0x00000000) 1725 ) 1726 self.assertTrue(result.ok()) 1727 self.assertEqual(result.value, '0x00000000') 1728 self.assertEqual(result.remaining, b'') 1729 1730 def test_pointer_0_with_multidigit_width(self) -> None: 1731 result = decode.FormatString('%11p').format( 1732 encode.encode_args(0x00000000) 1733 ) 1734 self.assertTrue(result.ok()) 1735 self.assertEqual(result.value, ' 0x00000000') 1736 self.assertEqual(result.remaining, b'') 1737 1738 def test_pointer_0_with_star_width(self) -> None: 1739 result = decode.FormatString('%*p').format( 1740 encode.encode_args(10, 0x00000000) 1741 ) 1742 self.assertTrue(result.ok()) 1743 self.assertEqual(result.value, '0x00000000') 1744 self.assertEqual(result.remaining, b'') 1745 1746 result = decode.FormatString('%*p').format( 1747 encode.encode_args(15, 0x00000000) 1748 ) 1749 self.assertTrue(result.ok()) 1750 self.assertEqual(result.value, ' 0x00000000') 1751 self.assertEqual(result.remaining, b'') 1752 1753 1754class TestFormattedString(unittest.TestCase): 1755 """Tests scoring how successfully a formatted string decoded.""" 1756 1757 def test_no_args(self) -> None: 1758 result = decode.FormatString('string').format(b'') 1759 1760 self.assertTrue(result.ok()) 1761 self.assertEqual(result.score(), (True, True, 0, 0, datetime.max)) 1762 1763 def test_one_arg(self) -> None: 1764 result = decode.FormatString('%d').format(encode.encode_args(0)) 1765 1766 self.assertTrue(result.ok()) 1767 self.assertEqual(result.score(), (True, True, 0, 1, datetime.max)) 1768 1769 def test_missing_args(self) -> None: 1770 result = decode.FormatString('%p%d%d').format(b'\x02\x80') 1771 1772 self.assertFalse(result.ok()) 1773 self.assertEqual(result.score(), (False, True, -2, 3, datetime.max)) 1774 self.assertGreater(result.score(), result.score(datetime.now())) 1775 self.assertGreater( 1776 result.score(datetime.now()), result.score(datetime.min) 1777 ) 1778 1779 def test_compare_score(self) -> None: 1780 all_args_ok = decode.FormatString('%d%d%d').format( 1781 encode.encode_args(0, 0, 0) 1782 ) 1783 missing_one_arg = decode.FormatString('%d%d%d').format( 1784 encode.encode_args(0, 0) 1785 ) 1786 missing_two_args = decode.FormatString('%d%d%d').format( 1787 encode.encode_args(0) 1788 ) 1789 all_args_extra_data = decode.FormatString('%d%d%d').format( 1790 encode.encode_args(0, 0, 0, 1) 1791 ) 1792 missing_one_arg_extra_data = decode.FormatString('%d%d%d').format( 1793 b'\0' + b'\x80' * 100 1794 ) 1795 1796 self.assertGreater(all_args_ok.score(), missing_one_arg.score()) 1797 self.assertGreater(missing_one_arg.score(), missing_two_args.score()) 1798 self.assertGreater( 1799 missing_two_args.score(), all_args_extra_data.score() 1800 ) 1801 self.assertGreater( 1802 all_args_extra_data.score(), missing_one_arg_extra_data.score() 1803 ) 1804 1805 1806if __name__ == '__main__': 1807 unittest.main() 1808