Print this page
11472 fix libdemangle rust changes


 222 {
 223         strview_t sv;
 224         strview_t name;
 225         uint64_t len;
 226         size_t rem;
 227         boolean_t last = B_FALSE;
 228 
 229         if (st->rds_error != 0 || sv_remaining(svp) == 0)
 230                 return (B_FALSE);
 231 
 232         sv_init_sv(&sv, svp);
 233 
 234         if (!rustdem_parse_num(st, &sv, &len)) {
 235                 DEMDEBUG("ERROR: no leading length");
 236                 st->rds_error = EINVAL;
 237                 return (B_FALSE);
 238         }
 239 
 240         rem = sv_remaining(&sv);
 241 
 242         if (rem < len || len == SIZE_MAX) {
 243                 st->rds_error = EINVAL;
 244                 return (B_FALSE);
 245         }
 246 
 247         /* Is this the last segment before the terminating E? */
 248         if (rem == len + 1) {
 249                 VERIFY3U(sv_peek(&sv, -1), ==, 'E');
 250                 last = B_TRUE;
 251         }
 252 
 253         if (!first && !rustdem_add_sep(st))
 254                 return (B_FALSE);
 255 
 256         /* Reduce length of seg to the length we parsed */
 257         (void) sv_init_sv_range(&name, &sv, len);
 258 
 259         DEMDEBUG("%s: segment='%.*s'", __func__, SV_PRINT(&name));
 260 
 261         /*
 262          * A rust hash starts with 'h', and is the last component of a name


 367                  * uppercase digits are used, and other rust demanglers all
 368                  * seem to assume the hash must contain lower-case hex digits.
 369                  */
 370                 case '0': case '1': case '2': case '3':
 371                 case '4': case '5': case '6': case '7':
 372                 case '8': case '9': case 'a': case 'b':
 373                 case 'c': case 'd': case 'e': case 'f':
 374                         if (!rustdem_append_c(st, c))
 375                                 return (B_FALSE);
 376                         break;
 377                 default:
 378                         return (B_FALSE);
 379                 }
 380         }
 381 
 382         sv_init_sv(svp, &sv);
 383         return (B_TRUE);
 384 }
 385 
 386 /*
 387  * A 10 digit value would imply a name 1Gb or larger in size.  It seems
 388  * unlikely to the point of absurdity any such value could every possibly
 389  * be valid (or even have compiled properly).  This also prevents the
 390  * uint64_t conversion from possibly overflowing since the value must always
 391  * be below 10 * UINT32_MAX.
 392  */
 393 #define MAX_DIGITS 10
 394 
 395 static boolean_t
 396 rustdem_parse_num(rustdem_state_t *restrict st, strview_t *restrict svp,
 397     uint64_t *restrict valp)
 398 {
 399         strview_t snum;
 400         uint64_t v = 0;
 401         size_t ndigits = 0;
 402         char c;
 403 
 404         if (st->rds_error != 0)
 405                 return (B_FALSE);
 406 
 407         sv_init_sv(&snum, svp);
 408 
 409         DEMDEBUG("%s: str='%.*s'", __func__, SV_PRINT(&snum));
 410 
 411         c = sv_peek(&snum, 0);
 412         if (!ISDIGIT(c)) {
 413                 DEMDEBUG("%s: ERROR no digits in str\n", __func__);




 222 {
 223         strview_t sv;
 224         strview_t name;
 225         uint64_t len;
 226         size_t rem;
 227         boolean_t last = B_FALSE;
 228 
 229         if (st->rds_error != 0 || sv_remaining(svp) == 0)
 230                 return (B_FALSE);
 231 
 232         sv_init_sv(&sv, svp);
 233 
 234         if (!rustdem_parse_num(st, &sv, &len)) {
 235                 DEMDEBUG("ERROR: no leading length");
 236                 st->rds_error = EINVAL;
 237                 return (B_FALSE);
 238         }
 239 
 240         rem = sv_remaining(&sv);
 241 
 242         if (rem < len) {
 243                 st->rds_error = EINVAL;
 244                 return (B_FALSE);
 245         }
 246 
 247         /* Is this the last segment before the terminating E? */
 248         if (rem == len + 1) {
 249                 VERIFY3U(sv_peek(&sv, -1), ==, 'E');
 250                 last = B_TRUE;
 251         }
 252 
 253         if (!first && !rustdem_add_sep(st))
 254                 return (B_FALSE);
 255 
 256         /* Reduce length of seg to the length we parsed */
 257         (void) sv_init_sv_range(&name, &sv, len);
 258 
 259         DEMDEBUG("%s: segment='%.*s'", __func__, SV_PRINT(&name));
 260 
 261         /*
 262          * A rust hash starts with 'h', and is the last component of a name


 367                  * uppercase digits are used, and other rust demanglers all
 368                  * seem to assume the hash must contain lower-case hex digits.
 369                  */
 370                 case '0': case '1': case '2': case '3':
 371                 case '4': case '5': case '6': case '7':
 372                 case '8': case '9': case 'a': case 'b':
 373                 case 'c': case 'd': case 'e': case 'f':
 374                         if (!rustdem_append_c(st, c))
 375                                 return (B_FALSE);
 376                         break;
 377                 default:
 378                         return (B_FALSE);
 379                 }
 380         }
 381 
 382         sv_init_sv(svp, &sv);
 383         return (B_TRUE);
 384 }
 385 
 386 /*
 387  * We have to pick an arbitrary limit here; 999,999,999 fits comfortably
 388  * within an int32_t, so let's go with that, as it seems unlikely we'd
 389  * ever see a larger value in context.


 390  */
 391 #define MAX_DIGITS 9
 392 
 393 static boolean_t
 394 rustdem_parse_num(rustdem_state_t *restrict st, strview_t *restrict svp,
 395     uint64_t *restrict valp)
 396 {
 397         strview_t snum;
 398         uint64_t v = 0;
 399         size_t ndigits = 0;
 400         char c;
 401 
 402         if (st->rds_error != 0)
 403                 return (B_FALSE);
 404 
 405         sv_init_sv(&snum, svp);
 406 
 407         DEMDEBUG("%s: str='%.*s'", __func__, SV_PRINT(&snum));
 408 
 409         c = sv_peek(&snum, 0);
 410         if (!ISDIGIT(c)) {
 411                 DEMDEBUG("%s: ERROR no digits in str\n", __func__);