@@ -1413,14 +1413,16 @@ Perl__mem_collxfrm(pTHX_ const char *input_string,
1413
1413
/* _mem_collxfrm() is a bit like strxfrm() but with two important
1414
1414
* differences. First, it handles embedded NULs. Second, it allocates a bit
1415
1415
* more memory than needed for the transformed data itself. The real
1416
- * transformed data begins at offset sizeof(collationix) . *xlen is set to
1416
+ * transformed data begins at offset COLLXFRM_HDR_LEN . *xlen is set to
1417
1417
* the length of that, and doesn't include the collation index size.
1418
1418
* Please see sv_collxfrm() to see how this is used. */
1419
1419
1420
+ #define COLLXFRM_HDR_LEN sizeof(PL_collation_ix)
1421
+
1420
1422
char * s = (char * ) input_string ;
1421
1423
STRLEN s_strlen = strlen (input_string );
1422
1424
char * xbuf = NULL ;
1423
- STRLEN xAlloc , xout ; /* xalloc is a reserved word in VC */
1425
+ STRLEN xAlloc ; /* xalloc is a reserved word in VC */
1424
1426
bool first_time = TRUE; /* Cleared after first loop iteration */
1425
1427
1426
1428
PERL_ARGS_ASSERT__MEM_COLLXFRM ;
@@ -1495,16 +1497,16 @@ Perl__mem_collxfrm(pTHX_ const char *input_string,
1495
1497
/* If something went wrong (which it shouldn't), just
1496
1498
* ignore this code point */
1497
1499
if ( x_len == 0
1498
- || strlen (x + sizeof ( PL_collation_ix ) ) < x_len )
1500
+ || strlen (x + COLLXFRM_HDR_LEN ) < x_len )
1499
1501
{
1500
1502
continue ;
1501
1503
}
1502
1504
1503
1505
/* If this character's transformation is lower than
1504
1506
* the current lowest, this one becomes the lowest */
1505
1507
if ( cur_min_x == NULL
1506
- || strLT (x + sizeof ( PL_collation_ix ) ,
1507
- cur_min_x + sizeof ( PL_collation_ix ) ))
1508
+ || strLT (x + COLLXFRM_HDR_LEN ,
1509
+ cur_min_x + COLLXFRM_HDR_LEN ))
1508
1510
{
1509
1511
strcpy (PL_strxfrm_min_char , cur_source );
1510
1512
cur_min_x = x ;
@@ -1629,8 +1631,8 @@ Perl__mem_collxfrm(pTHX_ const char *input_string,
1629
1631
/* If this character's transformation is higher than
1630
1632
* the current highest, this one becomes the highest */
1631
1633
if ( cur_max_x == NULL
1632
- || strGT (x + sizeof ( PL_collation_ix ) ,
1633
- cur_max_x + sizeof ( PL_collation_ix ) ))
1634
+ || strGT (x + COLLXFRM_HDR_LEN ,
1635
+ cur_max_x + COLLXFRM_HDR_LEN ))
1634
1636
{
1635
1637
PL_strxfrm_max_cp = j ;
1636
1638
cur_max_x = x ;
@@ -1684,7 +1686,7 @@ Perl__mem_collxfrm(pTHX_ const char *input_string,
1684
1686
/* The first element in the output is the collation id, used by
1685
1687
* sv_collxfrm(); then comes the space for the transformed string. The
1686
1688
* equation should give us a good estimate as to how much is needed */
1687
- xAlloc = sizeof ( PL_collation_ix )
1689
+ xAlloc = COLLXFRM_HDR_LEN
1688
1690
+ PL_collxfrm_base
1689
1691
+ (PL_collxfrm_mult * ((utf8 )
1690
1692
? utf8_length ((U8 * ) s , (U8 * ) s + len )
@@ -1695,30 +1697,28 @@ Perl__mem_collxfrm(pTHX_ const char *input_string,
1695
1697
1696
1698
/* Store the collation id */
1697
1699
* (U32 * )xbuf = PL_collation_ix ;
1698
- xout = sizeof (PL_collation_ix );
1699
1700
1700
1701
/* Then the transformation of the input. We loop until successful, or we
1701
1702
* give up */
1702
1703
for (;;) {
1703
- STRLEN xused = strxfrm (xbuf + xout , s , xAlloc - xout );
1704
+ * xlen = strxfrm (xbuf + COLLXFRM_HDR_LEN , s , xAlloc - COLLXFRM_HDR_LEN );
1704
1705
1705
1706
/* If the transformed string occupies less space than we told strxfrm()
1706
1707
* was available, it means it successfully transformed the whole
1707
1708
* string. */
1708
- if (xused < xAlloc - xout ) {
1709
- xout += xused ;
1709
+ if (* xlen < xAlloc - COLLXFRM_HDR_LEN ) {
1710
1710
break ;
1711
1711
}
1712
1712
1713
- if (UNLIKELY (xused >= PERL_INT_MAX ))
1713
+ if (UNLIKELY (* xlen >= PERL_INT_MAX ))
1714
1714
goto bad ;
1715
1715
1716
1716
/* A well-behaved strxfrm() returns exactly how much space it needs
1717
1717
* (not including the trailing NUL) when it fails due to not enough
1718
1718
* space being provided. Assume that this is the case unless it's been
1719
1719
* proven otherwise */
1720
1720
if (LIKELY (PL_strxfrm_is_behaved ) && first_time ) {
1721
- xAlloc = xused + sizeof ( PL_collation_ix ) + 1 ;
1721
+ xAlloc = * xlen + COLLXFRM_HDR_LEN + 1 ;
1722
1722
}
1723
1723
else { /* Here, either:
1724
1724
* 1) The strxfrm() has previously shown bad behavior; or
@@ -1742,10 +1742,9 @@ Perl__mem_collxfrm(pTHX_ const char *input_string,
1742
1742
first_time = FALSE;
1743
1743
}
1744
1744
1745
- * xlen = xout - sizeof (PL_collation_ix );
1746
1745
1747
1746
/* Free up unneeded space; retain ehough for trailing NUL */
1748
- Renew (xbuf , xout + 1 , char );
1747
+ Renew (xbuf , COLLXFRM_HDR_LEN + * xlen + 1 , char );
1749
1748
1750
1749
if (s != input_string ) {
1751
1750
Safefree (s );
0 commit comments