<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/158100>158100</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [libcxx] `operator>>(integer)`: incorrect hex prefix recognition for `basefield == 16`
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            libc++
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          morinmorin
      </td>
    </tr>
</table>

<pre>
    For `basefield == 16`, there is a small bug (L159 in `__locale_dir/num.h`) on how to recognize the prefix. As a result, reading from "10xFFx01" (with `basefield == 16`) consumes "10xFF".

Testcase:
```c++
#include <iostream>
#include <iomanip>
#include <sstream>

int main()
{
 std::istringstream is("10xFFx01");
    is >> std::setbase(16);

    int x;
    is >> x;
    bool failbit = is.fail();
    if (failbit) is.clear();
    auto next_pos = is.tellg();

    std::cout << "value: " << x << '\n'; // expected: 16, actual: 0
    std::cout << "fail: " << failbit << '\n'; // expected: 0, actual: 1
    std::cout << "next: " << next_pos << '\n'; // expected: 2 (1st 'x'), actual: 5 (2nd 'x')
}
```

The fix would be
```diff
--- a/libcxx/include/__locale_dir/num.h
+++ b/libcxx/include/__locale_dir/num.h
@@ -159 +159,4 @@ int __num_get<_CharT>::__stage2_int_loop(
-    if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0') {
+    if (
+        (__a_end - __a == 1 && __a_end[-1] == '0')
+     || (__a_end - __a == 2 && (__a_end[-2] == '+' || __a_end[-2] == '-') && __a_end[-1] == '0')
+) {
```
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJyUVU2v4yoP_jXuxmoFpOnHoot-TFfvcvYRSdyEVwQqIGdy76-_ctqc5ozOzJypUCPgsR9sPwYdo2kc0QHyE-SXhe5T68Oh88G48W9R-vqfw9UHhI0odaSbIVsjZBfILig3sBGgzphaCoQmosbYaWux7BsEtfufzPdoHBsXhfWVtlTUJoC6ur5btaP1Hr3D1v_A5DFQ5Rtn_iX2iPdANzOs8Mh-A8XeJiYLpGvjGrwF3yEoJcVwvQ5CglLM-cOk9nen3WPlXew7iu_GoNQKxBHE8TvFVOlIkPGM8eOoQJ14iCOozLjK9jUhZGfjYwqkO8i-fbLXaWfun23FD1biaFzCThsHagdqz2tb5sKYaj5IdjQxBeOahxmaOALngbNZNtogch3Ydfbt5SBS4nyA2snNO3aCu4TDZ9azxdJ7izdtbGkS5xNNXPH0eeKX8Y1L8ARyrk1cVZZ0-Bmo--TR0ZCKu4-Tx0TWNnPkE_weRuV7pj9DdubivWnbc6lwLP1jeXjtbyE_O_5kJwR1BXVFGu5UJWJ3rAd1Rl2lXlueiz-wjfF-JHtl5GuU4iOj_AMj5-cnxlnKvkY59oSMiZEDw9T-4yFyBihXzwGswMu8AZ7d0RLezIA_fG9rLGmOqM3tBuK4XC5Rg7paU1bDAOr6lD2o66c3ALfG6TGw_Du7tYC1wCVfMaBOMue41vhcZlEXheu7oqEE2bk4tzp8H4XNiS6KmHRDqjAuFdb7O6tOHJcvDReFLmjMimR1FoVGUBtQG5x2lo9FrsNlTPN8F_LTUkJ-mS4fUFvxSC4-mpsDfid7zfk3Y584HhfYlzlm_mB7hu35lz7fz_0CsFv10e1YoO3k69e45RTiX51zlpRJTYv6kNX7bK8XdJDbfLsR-VrIRXvI9lLu1rtql-_zvSCV7fIbbau6ppuscrVdmIMSKhd7KWW-zpRcUUZUS9plJWVaVBtYC-q0sStr37qVD83CxNjTQeY7KcTC6pJsHB9EpViNkz451EU4sNWy7JsIa2FNTPHlJ5lkx6f0KWKOeCP8nYJOPjwuVVA74xI1FDj8jeAONK7yIVCVsKXh-epNT2Ey3uHtd-_vog_20KZ0jyzt8QJoTGr7clX5jjvKvk2f5T34_1OVuL045gjq-gz77aD-CwAA__84ezQl">