@@ -1545,25 +1545,13 @@ fn extract_doc_comments(attrs: &[syn::Attribute]) -> Vec<String> {
1545
1545
}
1546
1546
1547
1547
// Unescapes a quoted string. char::escape_debug() was used to escape the text.
1548
- fn try_unescape ( s : & str ) -> Option < String > {
1549
- if s. is_empty ( ) {
1550
- return Some ( String :: new ( ) ) ;
1551
- }
1548
+ fn try_unescape ( mut s : & str ) -> Option < String > {
1549
+ s = s. strip_prefix ( '"' ) . unwrap_or ( s) ;
1550
+ s = s. strip_suffix ( '"' ) . unwrap_or ( s) ;
1552
1551
let mut result = String :: with_capacity ( s. len ( ) ) ;
1553
1552
let mut chars = s. chars ( ) ;
1554
- for i in 0 .. {
1555
- let c = match chars. next ( ) {
1556
- Some ( c) => c,
1557
- None => {
1558
- if result. ends_with ( '"' ) {
1559
- result. pop ( ) ;
1560
- }
1561
- return Some ( result) ;
1562
- }
1563
- } ;
1564
- if i == 0 && c == '"' {
1565
- // ignore it
1566
- } else if c == '\\' {
1553
+ while let Some ( c) = chars. next ( ) {
1554
+ if c == '\\' {
1567
1555
let c = chars. next ( ) ?;
1568
1556
match c {
1569
1557
't' => result. push ( '\t' ) ,
@@ -1586,30 +1574,17 @@ fn try_unescape(s: &str) -> Option<String> {
1586
1574
result. push ( c) ;
1587
1575
}
1588
1576
}
1589
- None
1577
+ Some ( result )
1590
1578
}
1591
1579
1592
1580
fn unescape_unicode ( chars : & mut Chars ) -> Option < ( char , char ) > {
1593
1581
let mut value = 0 ;
1594
- for i in 0 ..7 {
1595
- let c = chars. next ( ) ?;
1596
- let num = if c >= '0' && c <= '9' {
1597
- c as u32 - '0' as u32
1598
- } else if c >= 'a' && c <= 'f' {
1599
- c as u32 - 'a' as u32 + 10
1600
- } else if c >= 'A' && c <= 'F' {
1601
- c as u32 - 'A' as u32 + 10
1602
- } else {
1603
- if i == 0 {
1604
- return None ;
1605
- }
1606
- let decoded = char:: from_u32 ( value) ?;
1607
- return Some ( ( decoded, c) ) ;
1608
- } ;
1609
- if i >= 6 {
1610
- return None ;
1582
+ for ( i, c) in chars. enumerate ( ) {
1583
+ match ( i, c. to_digit ( 16 ) ) {
1584
+ ( 0 ..=5 , Some ( num) ) => value = ( value << 4 ) | num,
1585
+ ( 1 .., None ) => return Some ( ( char:: from_u32 ( value) ?, c) ) ,
1586
+ _ => break ,
1611
1587
}
1612
- value = ( value << 4 ) | num;
1613
1588
}
1614
1589
None
1615
1590
}
@@ -1713,3 +1688,23 @@ pub fn link_to(opts: BindgenAttrs) -> Result<ast::LinkToModule, Diagnostic> {
1713
1688
program. linked_modules . push ( module) ;
1714
1689
Ok ( ast:: LinkToModule ( program) )
1715
1690
}
1691
+
1692
+ #[ cfg( test) ]
1693
+ mod tests {
1694
+ #[ test]
1695
+ fn test_try_unescape ( ) {
1696
+ use super :: try_unescape;
1697
+ assert_eq ! ( try_unescape( "hello" ) . unwrap( ) , "hello" ) ;
1698
+ assert_eq ! ( try_unescape( "\" hello" ) . unwrap( ) , "hello" ) ;
1699
+ assert_eq ! ( try_unescape( "hello\" " ) . unwrap( ) , "hello" ) ;
1700
+ assert_eq ! ( try_unescape( "\" hello\" " ) . unwrap( ) , "hello" ) ;
1701
+ assert_eq ! ( try_unescape( "hello\\ \\ " ) . unwrap( ) , "hello\\ " ) ;
1702
+ assert_eq ! ( try_unescape( "hello\\ n" ) . unwrap( ) , "hello\n " ) ;
1703
+ assert_eq ! ( try_unescape( "hello\\ u" ) , None ) ;
1704
+ assert_eq ! ( try_unescape( "hello\\ u{" ) , None ) ;
1705
+ assert_eq ! ( try_unescape( "hello\\ u{}" ) , None ) ;
1706
+ assert_eq ! ( try_unescape( "hello\\ u{0}" ) . unwrap( ) , "hello\0 " ) ;
1707
+ assert_eq ! ( try_unescape( "hello\\ u{000000}" ) . unwrap( ) , "hello\0 " ) ;
1708
+ assert_eq ! ( try_unescape( "hello\\ u{0000000}" ) , None ) ;
1709
+ }
1710
+ }
0 commit comments