Ticket #138: new.patch

File new.patch, 37.8 KB (added by spitzak@…, 5 years ago)

Same patch but renamed so it displays correctly

  • api.c

    diff -ur original_src/api.c src/api.c
    old new  
    611611} 
    612612 
    613613/* 
    614  * Check if a string is a valid UTF-8 sequence. 
    615  * 
    616  * Check 'reader.c' for more details on UTF-8 encoding. 
    617  */ 
    618  
    619 static int 
    620 yaml_check_utf8(yaml_char_t *start, size_t length) 
    621 { 
    622     yaml_char_t *end = start+length; 
    623     yaml_char_t *pointer = start; 
    624  
    625     while (pointer < end) { 
    626         unsigned char octet; 
    627         unsigned int width; 
    628         unsigned int value; 
    629         size_t k; 
    630  
    631         octet = pointer[0]; 
    632         width = (octet & 0x80) == 0x00 ? 1 : 
    633                 (octet & 0xE0) == 0xC0 ? 2 : 
    634                 (octet & 0xF0) == 0xE0 ? 3 : 
    635                 (octet & 0xF8) == 0xF0 ? 4 : 0; 
    636         value = (octet & 0x80) == 0x00 ? octet & 0x7F : 
    637                 (octet & 0xE0) == 0xC0 ? octet & 0x1F : 
    638                 (octet & 0xF0) == 0xE0 ? octet & 0x0F : 
    639                 (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; 
    640         if (!width) return 0; 
    641         if (pointer+width > end) return 0; 
    642         for (k = 1; k < width; k ++) { 
    643             octet = pointer[k]; 
    644             if ((octet & 0xC0) != 0x80) return 0; 
    645             value = (value << 6) + (octet & 0x3F); 
    646         } 
    647         if (!((width == 1) || 
    648             (width == 2 && value >= 0x80) || 
    649             (width == 3 && value >= 0x800) || 
    650             (width == 4 && value >= 0x10000))) return 0; 
    651  
    652         pointer += width; 
    653     } 
    654  
    655     return 1; 
    656 } 
    657  
    658 /* 
    659614 * Create STREAM-START. 
    660615 */ 
    661616 
     
    731686                tag_directive != tag_directives_end; tag_directive ++) { 
    732687            assert(tag_directive->handle); 
    733688            assert(tag_directive->prefix); 
    734             if (!yaml_check_utf8(tag_directive->handle, 
    735                         strlen((char *)tag_directive->handle))) 
    736                 goto error; 
    737             if (!yaml_check_utf8(tag_directive->prefix, 
    738                         strlen((char *)tag_directive->prefix))) 
    739                 goto error; 
    740689            value.handle = yaml_strdup(tag_directive->handle); 
    741690            value.prefix = yaml_strdup(tag_directive->prefix); 
    742691            if (!value.handle || !value.prefix) goto error; 
     
    796745    assert(event);      /* Non-NULL event object is expected. */ 
    797746    assert(anchor);     /* Non-NULL anchor is expected. */ 
    798747 
    799     if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0; 
    800  
    801748    anchor_copy = yaml_strdup(anchor); 
    802749    if (!anchor_copy) 
    803750        return 0; 
     
    827774    assert(value);      /* Non-NULL anchor is expected. */ 
    828775 
    829776    if (anchor) { 
    830         if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error; 
    831777        anchor_copy = yaml_strdup(anchor); 
    832778        if (!anchor_copy) goto error; 
    833779    } 
    834780 
    835781    if (tag) { 
    836         if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; 
    837782        tag_copy = yaml_strdup(tag); 
    838783        if (!tag_copy) goto error; 
    839784    } 
     
    842787        length = strlen((char *)value); 
    843788    } 
    844789 
    845     if (!yaml_check_utf8(value, length)) goto error; 
    846790    value_copy = yaml_malloc(length+1); 
    847791    if (!value_copy) goto error; 
    848792    memcpy(value_copy, value, length); 
     
    877821    assert(event);      /* Non-NULL event object is expected. */ 
    878822 
    879823    if (anchor) { 
    880         if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error; 
    881824        anchor_copy = yaml_strdup(anchor); 
    882825        if (!anchor_copy) goto error; 
    883826    } 
    884827 
    885828    if (tag) { 
    886         if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; 
    887829        tag_copy = yaml_strdup(tag); 
    888830        if (!tag_copy) goto error; 
    889831    } 
     
    932874    assert(event);      /* Non-NULL event object is expected. */ 
    933875 
    934876    if (anchor) { 
    935         if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error; 
    936877        anchor_copy = yaml_strdup(anchor); 
    937878        if (!anchor_copy) goto error; 
    938879    } 
    939880 
    940881    if (tag) { 
    941         if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; 
    942882        tag_copy = yaml_strdup(tag); 
    943883        if (!tag_copy) goto error; 
    944884    } 
     
    10721012                tag_directive != tag_directives_end; tag_directive ++) { 
    10731013            assert(tag_directive->handle); 
    10741014            assert(tag_directive->prefix); 
    1075             if (!yaml_check_utf8(tag_directive->handle, 
    1076                         strlen((char *)tag_directive->handle))) 
    1077                 goto error; 
    1078             if (!yaml_check_utf8(tag_directive->prefix, 
    1079                         strlen((char *)tag_directive->prefix))) 
    1080                 goto error; 
    10811015            value.handle = yaml_strdup(tag_directive->handle); 
    10821016            value.prefix = yaml_strdup(tag_directive->prefix); 
    10831017            if (!value.handle || !value.prefix) goto error; 
     
    12101144        tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG; 
    12111145    } 
    12121146 
    1213     if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; 
    12141147    tag_copy = yaml_strdup(tag); 
    12151148    if (!tag_copy) goto error; 
    12161149 
     
    12181151        length = strlen((char *)value); 
    12191152    } 
    12201153 
    1221     if (!yaml_check_utf8(value, length)) goto error; 
    12221154    value_copy = yaml_malloc(length+1); 
    12231155    if (!value_copy) goto error; 
    12241156    memcpy(value_copy, value, length); 
     
    12621194        tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG; 
    12631195    } 
    12641196 
    1265     if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; 
    12661197    tag_copy = yaml_strdup(tag); 
    12671198    if (!tag_copy) goto error; 
    12681199 
     
    13071238        tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG; 
    13081239    } 
    13091240 
    1310     if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; 
    13111241    tag_copy = yaml_strdup(tag); 
    13121242    if (!tag_copy) goto error; 
    13131243 
  • emitter.c

    diff -ur original_src/emitter.c src/emitter.c
    old new  
    3737         1)) 
    3838 
    3939/* 
    40  * Copy a character from a string into buffer. 
     40 * Copy a byte from a string into buffer. 
    4141 */ 
    4242 
    4343#define WRITE(emitter,string)                                                   \ 
     
    4646         emitter->column ++,                                                    \ 
    4747         1)) 
    4848 
     49#define WRITEN(emitter,string,n)                                                \ 
     50    (FLUSH(emitter)                                                             \ 
     51     && (COPYN(emitter->buffer,string,n),                                       \ 
     52         emitter->column ++,                                                    \ 
     53         1)) 
     54 
    4955/* 
    5056 * Copy a line break character from a string into buffer. 
    5157 */ 
     
    5662         (PUT_BREAK(emitter),                                                   \ 
    5763          string.pointer ++,                                                    \ 
    5864          1) :                                                                  \ 
    59          (COPY(emitter->buffer,string),                                         \ 
     65         (COPYN(emitter->buffer,string,WIDTH(string)),                          \ 
    6066          emitter->column = 0,                                                  \ 
    6167          emitter->line ++,                                                     \ 
    6268          1))) 
     
    14581464    return 1; 
    14591465} 
    14601466 
     1467/** 
     1468  Return the number of bytes in the next UTF-8 character. 
     1469 
     1470  Returns 0 for any error, includinge incorrect bytes, not enough 
     1471  bytes before the end pointer, and overlong encodings. If 0 is 
     1472  returned, pointer[0] will always have the high bit set and will 
     1473  thus never match any ASCII character. 
     1474 
     1475  The encodings of surrogate halves are allowed! Otherwise it is not 
     1476  possible to losslessly encode invalid UTF-16 into UTF-8.  (There is 
     1477  a vocal contingent trying to sabotage UTF-8 by declaring surrogate 
     1478  half encodings invalid. Anybody such claim should be investigated 
     1479  carefully: if that user's code does not also reject invalid UTF-16, 
     1480  then they are being hypocrites and can be ignored.) 
     1481*/ 
     1482static unsigned int utf8_width(yaml_char_t* pointer, yaml_char_t* end) 
     1483{ 
     1484    unsigned char octet = pointer[0]; 
     1485    if (octet < 0x80) { 
     1486        /* 1-byte character */ 
     1487        return 1; 
     1488    } else if (octet < 0xC2) { 
     1489        /* continuation byte or overlong 2-byte encoding */ 
     1490        return 0; 
     1491    } else if (octet < 0xE0) { 
     1492        /* 2-byte character */ 
     1493        if (end-pointer < 2) return 0; 
     1494        if ((pointer[1] & 0xC0) != 0x80) return 0; 
     1495        return 2; 
     1496    } else if (octet < 0xF0) { 
     1497        /* 3-byte character */ 
     1498        if (end-pointer < 3) return 0; 
     1499        if (octet == 0xE0 && pointer[1] < 0xA0) return 0; /* overlong */ 
     1500        if ((pointer[1] & 0xC0) != 0x80) return 0; 
     1501        if ((pointer[2] & 0xC0) != 0x80) return 0; 
     1502        return 3; 
     1503    } else if (octet < 0xF5) { 
     1504        /* 4-byte character */ 
     1505        if (end-pointer < 4) return 0; 
     1506        if (octet == 0xF0 && pointer[1] < 0x90) return 0; /* overlong */ 
     1507        if (octet == 0xF4 && pointer[1] > 0x8F) return 0; /* > 0x10FFFF */ 
     1508        if ((pointer[1] & 0xC0) != 0x80) return 0; 
     1509        if ((pointer[2] & 0xC0) != 0x80) return 0; 
     1510        if ((pointer[3] & 0xC0) != 0x80) return 0; 
     1511        return 4; 
     1512    } else { 
     1513        /* can never appear in UTF-8 */ 
     1514        return 0; 
     1515    } 
     1516} 
     1517 
    14611518/* 
    14621519 * Check if a scalar is valid. 
    14631520 */ 
     
    14811538    int space_break = 0; 
    14821539 
    14831540    int preceeded_by_whitespace = 0; 
    1484     int followed_by_whitespace = 0; 
    14851541    int previous_space = 0; 
    14861542    int previous_break = 0; 
    14871543 
     
    15101566    } 
    15111567 
    15121568    preceeded_by_whitespace = 1; 
    1513     followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string)); 
    15141569 
    15151570    while (string.pointer != string.end) 
    15161571    { 
     1572        unsigned int width = utf8_width(string.pointer, string.end); 
     1573 
     1574        if (!width) { 
     1575            special_characters = 1; 
     1576            string.pointer++; 
     1577            continue; 
     1578        } 
     1579 
    15171580        if (string.start == string.pointer) 
    15181581        { 
    15191582            if (CHECK(string, '#') || CHECK(string, ',') 
     
    15301593 
    15311594            if (CHECK(string, '?') || CHECK(string, ':')) { 
    15321595                flow_indicators = 1; 
    1533                 if (followed_by_whitespace) { 
     1596                if (IS_BLANKZ_AT(string, 1)) { 
    15341597                    block_indicators = 1; 
    15351598                } 
    15361599            } 
    15371600 
    1538             if (CHECK(string, '-') && followed_by_whitespace) { 
     1601            if (CHECK(string, '-') && IS_BLANKZ_AT(string, 1)) { 
    15391602                flow_indicators = 1; 
    15401603                block_indicators = 1; 
    15411604            } 
     
    15501613 
    15511614            if (CHECK(string, ':')) { 
    15521615                flow_indicators = 1; 
    1553                 if (followed_by_whitespace) { 
     1616                if (IS_BLANKZ_AT(string, 1)) { 
    15541617                    block_indicators = 1; 
    15551618                } 
    15561619            } 
     
    15661629            special_characters = 1; 
    15671630        } 
    15681631 
    1569         if (IS_BREAK(string)) { 
    1570             line_breaks = 1; 
    1571         } 
    1572  
    15731632        if (IS_SPACE(string)) 
    15741633        { 
    15751634            if (string.start == string.pointer) { 
     
    15861645        } 
    15871646        else if (IS_BREAK(string)) 
    15881647        { 
     1648            line_breaks = 1; 
    15891649            if (string.start == string.pointer) { 
    15901650                leading_break = 1; 
    15911651            } 
     
    16051665        } 
    16061666 
    16071667        preceeded_by_whitespace = IS_BLANKZ(string); 
    1608         MOVE(string); 
    1609         if (string.pointer != string.end) { 
    1610             followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string)); 
    1611         } 
     1668        MOVEN(string, width); 
    16121669    } 
    16131670 
    16141671    emitter->scalar_data.multiline = line_breaks; 
     
    18511908            if (!WRITE(emitter, string)) return 0; 
    18521909        } 
    18531910        else { 
    1854             int width = WIDTH(string); 
    1855             unsigned int value; 
    1856             while (width --) { 
    1857                 value = *(string.pointer++); 
    1858                 if (!PUT(emitter, '%')) return 0; 
    1859                 if (!PUT(emitter, (value >> 4) 
    1860                             + ((value >> 4) < 10 ? '0' : 'A' - 10))) 
    1861                     return 0; 
    1862                 if (!PUT(emitter, (value & 0x0F) 
    1863                             + ((value & 0x0F) < 10 ? '0' : 'A' - 10))) 
    1864                     return 0; 
    1865             } 
     1911            /* %-encode all other bytes, including valid and invalid UTF-8 */ 
     1912            unsigned char value = *(string.pointer++); 
     1913            if (!PUT(emitter, '%')) return 0; 
     1914            if (!PUT(emitter, (value >> 4) 
     1915                     + ((value >> 4) < 10 ? '0' : 'A' - 10))) 
     1916                return 0; 
     1917            if (!PUT(emitter, (value & 0x0F) 
     1918                     + ((value & 0x0F) < 10 ? '0' : 'A' - 10))) 
     1919                return 0; 
    18661920        } 
    18671921    } 
    18681922 
     
    19912045    return 1; 
    19922046} 
    19932047 
     2048static unsigned char utf8_mask[5] = {0xFF, 0x7F, 0x1F, 0x0F, 0x07}; 
     2049 
    19942050static int 
    19952051yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter, 
    19962052        yaml_char_t *value, size_t length, int allow_breaks) 
     
    20032059 
    20042060    while (string.pointer != string.end) 
    20052061    { 
     2062        unsigned int width = utf8_width(string.pointer, string.end); 
     2063 
     2064        if (width == 0) { 
     2065            /* 
     2066              UTF-8 encoding error.  This is a byte with the high bit 
     2067              set.  The parser has been altered to read \XNN as a raw 
     2068              byte.  I would prefer to use lowercase x but the old 
     2069              writer produces that for legal UTF-8 encodings of 
     2070              U+0080..U+00FF. It is not clear what other parsers will 
     2071              do with this, though previous libyaml threw an error. 
     2072            */ 
     2073            unsigned int value = string.pointer[0]; 
     2074            int digit; 
     2075            if (!PUT(emitter, '\\')) return 0; 
     2076            if (!PUT(emitter, 'X')) return 0; 
     2077            digit = (value >> 4) & 0x0F; 
     2078            if (!PUT(emitter, digit + (digit < 10 ? '0' : 'A'-10))) return 0; 
     2079            digit = value & 0x0F; 
     2080            if (!PUT(emitter, digit + (digit < 10 ? '0' : 'A'-10))) return 0; 
     2081            MOVE(string); 
     2082            spaces = 0; 
     2083            continue; 
     2084        } 
     2085 
    20062086        if (!IS_PRINTABLE(string) || (!emitter->unicode && !IS_ASCII(string)) 
    20072087                || IS_BOM(string) || IS_BREAK(string) 
    20082088                || CHECK(string, '"') || CHECK(string, '\\')) 
    20092089        { 
    2010             unsigned char octet; 
    2011             unsigned int width; 
    20122090            unsigned int value; 
    20132091            int k; 
    20142092 
    2015             octet = string.pointer[0]; 
    2016             width = (octet & 0x80) == 0x00 ? 1 : 
    2017                     (octet & 0xE0) == 0xC0 ? 2 : 
    2018                     (octet & 0xF0) == 0xE0 ? 3 : 
    2019                     (octet & 0xF8) == 0xF0 ? 4 : 0; 
    2020             value = (octet & 0x80) == 0x00 ? octet & 0x7F : 
    2021                     (octet & 0xE0) == 0xC0 ? octet & 0x1F : 
    2022                     (octet & 0xF0) == 0xE0 ? octet & 0x0F : 
    2023                     (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; 
     2093            value = string.pointer[0] & utf8_mask[width]; 
    20242094            for (k = 1; k < (int)width; k ++) { 
    2025                 octet = string.pointer[k]; 
    2026                 value = (value << 6) + (octet & 0x3F); 
     2095                value = (value << 6) + (string.pointer[k] & 0x3F); 
    20272096            } 
    20282097            string.pointer += width; 
    20292098 
     
    20922161                    break; 
    20932162 
    20942163                default: 
    2095                     if (value <= 0xFF) { 
     2164                    // \xNN sequence is disabled so that it may be used in the 
     2165                    // future for invalid byte sequences 
     2166                    /*if (value <= 0xFF) { 
    20962167                        if (!PUT(emitter, 'x')) return 0; 
    20972168                        width = 2; 
    20982169                    } 
    2099                     else if (value <= 0xFFFF) { 
     2170                    else*/ if (value <= 0xFFFF) { 
    21002171                        if (!PUT(emitter, 'u')) return 0; 
    21012172                        width = 4; 
    21022173                    } 
     
    21312202        } 
    21322203        else 
    21332204        { 
    2134             if (!WRITE(emitter, string)) return 0; 
     2205            if (!WRITEN(emitter, string, width)) return 0; 
    21352206            spaces = 0; 
    21362207        } 
    21372208    } 
  • reader.c

    diff -ur original_src/reader.c src/reader.c
    old new  
    187187        while (parser->raw_buffer.pointer != parser->raw_buffer.last) 
    188188        { 
    189189            unsigned int value = 0, value2 = 0; 
    190             int incomplete = 0; 
    191190            unsigned char octet; 
    192191            unsigned int width = 0; 
    193192            int low, high; 
     
    199198            switch (parser->encoding) 
    200199            { 
    201200                case YAML_UTF8_ENCODING: 
    202  
    203                     /* 
    204                      * Decode a UTF-8 character.  Check RFC 3629 
    205                      * (http://www.ietf.org/rfc/rfc3629.txt) for more details. 
    206                      * 
    207                      * The following table (taken from the RFC) is used for 
    208                      * decoding. 
    209                      * 
    210                      *    Char. number range |        UTF-8 octet sequence 
    211                      *      (hexadecimal)    |              (binary) 
    212                      *   --------------------+------------------------------------ 
    213                      *   0000 0000-0000 007F | 0xxxxxxx 
    214                      *   0000 0080-0000 07FF | 110xxxxx 10xxxxxx 
    215                      *   0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx 
    216                      *   0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 
    217                      * 
    218                      * Additionally, the characters in the range 0xD800-0xDFFF 
    219                      * are prohibited as they are reserved for use with UTF-16 
    220                      * surrogate pairs. 
    221                      */ 
    222  
    223                     /* Determine the length of the UTF-8 sequence. */ 
    224  
    225201                    octet = parser->raw_buffer.pointer[0]; 
    226                     width = (octet & 0x80) == 0x00 ? 1 : 
    227                             (octet & 0xE0) == 0xC0 ? 2 : 
    228                             (octet & 0xF0) == 0xE0 ? 3 : 
    229                             (octet & 0xF8) == 0xF0 ? 4 : 0; 
    230  
    231                     /* Check if the leading octet is valid. */ 
    232  
    233                     if (!width) 
    234                         return yaml_parser_set_reader_error(parser, 
    235                                 "Invalid leading UTF-8 octet", 
    236                                 parser->offset, octet); 
    237  
    238                     /* Check if the raw buffer contains an incomplete character. */ 
    239  
    240                     if (width > raw_unread) { 
    241                         if (parser->eof) { 
    242                             return yaml_parser_set_reader_error(parser, 
    243                                     "Incomplete UTF-8 octet sequence", 
    244                                     parser->offset, -1); 
    245                         } 
    246                         incomplete = 1; 
    247                         break; 
    248                     } 
    249  
    250                     /* Decode the leading octet. */ 
    251  
    252                     value = (octet & 0x80) == 0x00 ? octet & 0x7F : 
    253                             (octet & 0xE0) == 0xC0 ? octet & 0x1F : 
    254                             (octet & 0xF0) == 0xE0 ? octet & 0x0F : 
    255                             (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; 
    256  
    257                     /* Check and decode the trailing octets. */ 
    258  
    259                     for (k = 1; k < width; k ++) 
    260                     { 
    261                         octet = parser->raw_buffer.pointer[k]; 
    262  
    263                         /* Check if the octet is valid. */ 
    264  
    265                         if ((octet & 0xC0) != 0x80) 
    266                             return yaml_parser_set_reader_error(parser, 
    267                                     "Invalid trailing UTF-8 octet", 
    268                                     parser->offset+k, octet); 
    269  
    270                         /* Decode the octet. */ 
    271  
    272                         value = (value << 6) + (octet & 0x3F); 
    273                     } 
    274  
    275                     /* Check the length of the sequence against the value. */ 
    276  
    277                     if (!((width == 1) || 
    278                             (width == 2 && value >= 0x80) || 
    279                             (width == 3 && value >= 0x800) || 
    280                             (width == 4 && value >= 0x10000))) 
    281                         return yaml_parser_set_reader_error(parser, 
    282                                 "Invalid length of a UTF-8 sequence", 
    283                                 parser->offset, -1); 
    284  
    285                     /* Check the range of the value. */ 
    286  
    287                     if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) 
     202                    /* 
     203                      We can only disallow characters without the high 
     204                      bit set. Characters with the high bit set are required 
     205                      for invalid UTF-8 strings to be encoded, as we 
     206                      cannot rely on any backslash sequences working. 
     207                    */ 
     208                    if (! (octet == 0x09 || octet == 0x0A || octet == 0x0D 
     209                           || (octet >= 0x20 && octet != 0x7F) )) 
    288210                        return yaml_parser_set_reader_error(parser, 
    289                                 "Invalid Unicode character", 
     211                                "Control characters are not allowed", 
    290212                                parser->offset, value); 
    291213 
     214                    parser->raw_buffer.pointer++; 
     215                    parser->offset++; 
     216                    *(parser->buffer.last++) = octet; 
    292217                    break; 
    293218                 
    294219                case YAML_UTF16LE_ENCODING: 
     
    331256                                    "Incomplete UTF-16 character", 
    332257                                    parser->offset, -1); 
    333258                        } 
    334                         incomplete = 1; 
    335259                        break; 
    336260                    } 
    337261 
     
    339263 
    340264                    value = parser->raw_buffer.pointer[low] 
    341265                        + (parser->raw_buffer.pointer[high] << 8); 
    342  
    343                     /* Check for unexpected low surrogate area. */ 
    344  
    345                     if ((value & 0xFC00) == 0xDC00) 
    346                         return yaml_parser_set_reader_error(parser, 
    347                                 "Unexpected low surrogate area", 
    348                                 parser->offset, value); 
     266                    width = 2; 
    349267 
    350268                    /* Check for a high surrogate area. */ 
    351269 
    352270                    if ((value & 0xFC00) == 0xD800) { 
    353271 
    354                         width = 4; 
    355  
    356272                        /* Check for incomplete surrogate pair. */ 
    357273 
    358274                        if (raw_unread < 4) { 
    359                             if (parser->eof) { 
    360                                 return yaml_parser_set_reader_error(parser, 
    361                                         "Incomplete UTF-16 surrogate pair", 
    362                                         parser->offset, -1); 
     275                            if (parser->eof) { /* trailing high surrogate */ 
     276                                width = 2; 
     277                            } else { 
     278                                break; /* Can't tell until we have more raw characters */ 
     279                            } 
     280                        } else { 
     281 
     282                            /* Get the next character. */ 
     283 
     284                            value2 = parser->raw_buffer.pointer[low+2] 
     285                                + (parser->raw_buffer.pointer[high+2] << 8); 
     286 
     287                            /* Check for a low surrogate area. */ 
     288                            if ((value2 & 0xFC00) == 0xDC00) { 
     289                                width = 4; 
     290                                /* Generate the value of the surrogate pair. */ 
     291                                value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF); 
    363292                            } 
    364                             incomplete = 1; 
    365                             break; 
    366293                        } 
     294                    } 
    367295 
    368                         /* Get the next character. */ 
     296                    /* Check if the raw buffer contains enough bytes to form a character. */ 
    369297 
    370                         value2 = parser->raw_buffer.pointer[low+2] 
    371                             + (parser->raw_buffer.pointer[high+2] << 8); 
     298                    /* 
     299                     * Check if the character is in the allowed range: 
     300                     *      #x9 | #xA | #xD | [#x20-#x7E]               (8 bit) 
     301                     *      | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD]    (16 bit) 
     302                     *      | [#x10000-#x10FFFF]                        (32 bit) 
     303                     */ 
     304                    /* Modified to allow all 16-bit values as \uNNNN may not 
     305                     work for some parsers for these values. */ 
     306                    if (! (value == 0x09 || value == 0x0A || value == 0x0D 
     307                           || (value >= 0x20 && value <= 0x7E) 
     308                           || (value == 0x85) || value >= 0xA0)) 
     309                        return yaml_parser_set_reader_error(parser, 
     310                                "Control characters are not allowed", 
     311                                parser->offset, value); 
    372312 
    373                         /* Check for a low surrogate area. */ 
     313                    /* Move the raw pointers. */ 
    374314 
    375                         if ((value2 & 0xFC00) != 0xDC00) 
    376                             return yaml_parser_set_reader_error(parser, 
    377                                     "Expected low surrogate area", 
    378                                     parser->offset+2, value2); 
     315                    parser->raw_buffer.pointer += width; 
     316                    parser->offset += width; 
    379317 
    380                         /* Generate the value of the surrogate pair. */ 
     318                    /* Finally put the character into the buffer. */ 
    381319 
    382                         value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF); 
     320                    /* 0000 0000-0000 007F -> 0xxxxxxx */ 
     321                    if (value <= 0x7F) { 
     322                        *(parser->buffer.last++) = value; 
    383323                    } 
    384  
     324                    /* 0000 0080-0000 07FF -> 110xxxxx 10xxxxxx */ 
     325                    else if (value <= 0x7FF) { 
     326                        *(parser->buffer.last++) = 0xC0 + (value >> 6); 
     327                        *(parser->buffer.last++) = 0x80 + (value & 0x3F); 
     328                    } 
     329                    /* 0000 0800-0000 FFFF -> 1110xxxx 10xxxxxx 10xxxxxx */ 
     330                    else if (value <= 0xFFFF) { 
     331                        *(parser->buffer.last++) = 0xE0 + (value >> 12); 
     332                        *(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F); 
     333                        *(parser->buffer.last++) = 0x80 + (value & 0x3F); 
     334                    } 
     335                    /* 0001 0000-0010 FFFF -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ 
    385336                    else { 
    386                         width = 2; 
     337                        *(parser->buffer.last++) = 0xF0 + (value >> 18); 
     338                        *(parser->buffer.last++) = 0x80 + ((value >> 12) & 0x3F); 
     339                        *(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F); 
     340                        *(parser->buffer.last++) = 0x80 + (value & 0x3F); 
    387341                    } 
    388  
    389342                    break; 
    390343 
    391344                default: 
    392345                    assert(1);      /* Impossible. */ 
    393346            } 
    394347 
    395             /* Check if the raw buffer contains enough bytes to form a character. */ 
    396  
    397             if (incomplete) break; 
    398  
    399             /* 
    400              * Check if the character is in the allowed range: 
    401              *      #x9 | #xA | #xD | [#x20-#x7E]               (8 bit) 
    402              *      | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD]    (16 bit) 
    403              *      | [#x10000-#x10FFFF]                        (32 bit) 
    404              */ 
    405  
    406             if (! (value == 0x09 || value == 0x0A || value == 0x0D 
    407                         || (value >= 0x20 && value <= 0x7E) 
    408                         || (value == 0x85) || (value >= 0xA0 && value <= 0xD7FF) 
    409                         || (value >= 0xE000 && value <= 0xFFFD) 
    410                         || (value >= 0x10000 && value <= 0x10FFFF))) 
    411                 return yaml_parser_set_reader_error(parser, 
    412                         "Control characters are not allowed", 
    413                         parser->offset, value); 
    414  
    415             /* Move the raw pointers. */ 
    416  
    417             parser->raw_buffer.pointer += width; 
    418             parser->offset += width; 
    419  
    420             /* Finally put the character into the buffer. */ 
    421  
    422             /* 0000 0000-0000 007F -> 0xxxxxxx */ 
    423             if (value <= 0x7F) { 
    424                 *(parser->buffer.last++) = value; 
    425             } 
    426             /* 0000 0080-0000 07FF -> 110xxxxx 10xxxxxx */ 
    427             else if (value <= 0x7FF) { 
    428                 *(parser->buffer.last++) = 0xC0 + (value >> 6); 
    429                 *(parser->buffer.last++) = 0x80 + (value & 0x3F); 
    430             } 
    431             /* 0000 0800-0000 FFFF -> 1110xxxx 10xxxxxx 10xxxxxx */ 
    432             else if (value <= 0xFFFF) { 
    433                 *(parser->buffer.last++) = 0xE0 + (value >> 12); 
    434                 *(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F); 
    435                 *(parser->buffer.last++) = 0x80 + (value & 0x3F); 
    436             } 
    437             /* 0001 0000-0010 FFFF -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ 
    438             else { 
    439                 *(parser->buffer.last++) = 0xF0 + (value >> 18); 
    440                 *(parser->buffer.last++) = 0x80 + ((value >> 12) & 0x3F); 
    441                 *(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F); 
    442                 *(parser->buffer.last++) = 0x80 + (value & 0x3F); 
    443             } 
    444  
    445348            parser->unread ++; 
    446349        } 
    447350 
  • scanner.c

    diff -ur original_src/scanner.c src/scanner.c
    old new  
    495495     (parser->mark.index ++,                                                    \ 
    496496      parser->mark.column ++,                                                   \ 
    497497      parser->unread --,                                                        \ 
    498       parser->buffer.pointer += WIDTH(parser->buffer)) 
     498      parser->buffer.pointer ++) 
    499499 
     500#define SKIPN(parser,n)                                                         \ 
     501     (parser->mark.index ++,                                                    \ 
     502      parser->mark.column ++,                                                   \ 
     503      parser->unread --,                                                        \ 
     504      parser->buffer.pointer += (n)) 
    500505#define SKIP_LINE(parser)                                                       \ 
    501506     (IS_CRLF(parser->buffer) ?                                                 \ 
    502507      (parser->mark.index += 2,                                                 \ 
     
    523528          parser->unread --,                                                    \ 
    524529          1) : 0) 
    525530 
     531#define READN(parser,string,n)                                                  \ 
     532     (STRING_EXTEND(parser,string) ?                                            \ 
     533         (COPYN(string,parser->buffer,n),                                       \ 
     534          parser->mark.index ++,                                                \ 
     535          parser->mark.column ++,                                               \ 
     536          parser->unread --,                                                    \ 
     537          1) : 0) 
     538 
    526539/* 
    527540 * Copy a line break character to a string buffer and advance pointers. 
    528541 */ 
     
    19241937        if (!CACHE(parser, 1)) return 0; 
    19251938 
    19261939        if (parser->mark.column == 0 && IS_BOM(parser->buffer)) 
    1927             SKIP(parser); 
     1940            SKIPN(parser,3); /* UTF-8 BOM is 3 bytes */ 
    19281941 
    19291942        /* 
    19301943         * Eat whitespaces. 
     
    26572670yaml_parser_scan_uri_escapes(yaml_parser_t *parser, int directive, 
    26582671        yaml_mark_t start_mark, yaml_string_t *string) 
    26592672{ 
    2660     int width = 0; 
    2661  
    2662     /* Decode the required number of characters. */ 
    2663  
    2664     do { 
    2665  
    2666         unsigned char octet = 0; 
    2667  
    2668         /* Check for a URI-escaped octet. */ 
    2669  
    2670         if (!CACHE(parser, 3)) return 0; 
    2671  
    2672         if (!(CHECK(parser->buffer, '%') 
    2673                     && IS_HEX_AT(parser->buffer, 1) 
    2674                     && IS_HEX_AT(parser->buffer, 2))) { 
    2675             return yaml_parser_set_scanner_error(parser, directive ? 
    2676                     "while parsing a %TAG directive" : "while parsing a tag", 
    2677                     start_mark, "did not find URI escaped octet"); 
    2678         } 
    2679  
    2680         /* Get the octet. */ 
     2673    unsigned char octet = 0; 
    26812674 
    2682         octet = (AS_HEX_AT(parser->buffer, 1) << 4) + AS_HEX_AT(parser->buffer, 2); 
     2675    /* Check for a URI-escaped octet. */ 
    26832676 
    2684         /* If it is the leading octet, determine the length of the UTF-8 sequence. */ 
     2677    if (!CACHE(parser, 3)) return 0; 
    26852678 
    2686         if (!width) 
    2687         { 
    2688             width = (octet & 0x80) == 0x00 ? 1 : 
    2689                     (octet & 0xE0) == 0xC0 ? 2 : 
    2690                     (octet & 0xF0) == 0xE0 ? 3 : 
    2691                     (octet & 0xF8) == 0xF0 ? 4 : 0; 
    2692             if (!width) { 
    2693                 return yaml_parser_set_scanner_error(parser, directive ? 
    2694                         "while parsing a %TAG directive" : "while parsing a tag", 
    2695                         start_mark, "found an incorrect leading UTF-8 octet"); 
    2696             } 
    2697         } 
    2698         else 
    2699         { 
    2700             /* Check if the trailing octet is correct. */ 
     2679    if (!(CHECK(parser->buffer, '%') 
     2680          && IS_HEX_AT(parser->buffer, 1) 
     2681          && IS_HEX_AT(parser->buffer, 2))) { 
     2682        return yaml_parser_set_scanner_error(parser, directive ? 
     2683                "while parsing a %TAG directive" : "while parsing a tag", 
     2684                start_mark, "did not find URI escaped octet"); 
     2685    } 
    27012686 
    2702             if ((octet & 0xC0) != 0x80) { 
    2703                 return yaml_parser_set_scanner_error(parser, directive ? 
    2704                         "while parsing a %TAG directive" : "while parsing a tag", 
    2705                         start_mark, "found an incorrect trailing UTF-8 octet"); 
    2706             } 
    2707         } 
     2687    /* Get the octet. */ 
    27082688 
    2709         /* Copy the octet and move the pointers. */ 
     2689    octet = (AS_HEX_AT(parser->buffer, 1) << 4) + AS_HEX_AT(parser->buffer, 2); 
    27102690 
    2711         *(string->pointer++) = octet; 
    2712         SKIP(parser); 
    2713         SKIP(parser); 
    2714         SKIP(parser); 
     2691    /* Copy the octet and move the pointers. */ 
    27152692 
    2716     } while (--width); 
     2693    *(string->pointer++) = octet; 
     2694    SKIP(parser); 
     2695    SKIP(parser); 
     2696    SKIP(parser); 
    27172697 
    27182698    return 1; 
    27192699} 
     
    31023082            else if (!single && CHECK(parser->buffer, '\\')) 
    31033083            { 
    31043084                size_t code_length = 0; 
     3085                int raw_code = 0; 
    31053086 
    31063087                if (!STRING_EXTEND(parser, string)) goto error; 
    31073088 
     
    31883169                        code_length = 2; 
    31893170                        break; 
    31903171 
     3172                    case 'X': 
     3173                        code_length = 2; 
     3174                        raw_code = 1; 
     3175                        break; 
     3176 
    31913177                    case 'u': 
    31923178                        code_length = 4; 
    31933179                        break; 
     
    32333219                        goto error; 
    32343220                    } 
    32353221 
    3236                     if (value <= 0x7F) { 
     3222                    if (value <= 0x7F || raw_code) { 
    32373223                        *(string.pointer++) = value; 
    32383224                    } 
    32393225                    else if (value <= 0x7FF) { 
     
    32623248 
    32633249            else 
    32643250            { 
    3265                 /* It is a non-escaped non-blank character. */ 
     3251                /* It is a non-escaped non-blank byte. */ 
    32663252 
    32673253                if (!READ(parser, string)) goto error; 
    32683254            } 
     
    34743460                } 
    34753461            } 
    34763462 
    3477             /* Copy the character. */ 
     3463            /* Copy the byte. */ 
    34783464 
    34793465            if (!READ(parser, string)) goto error; 
    34803466 
  • yaml_private.h

    diff -ur original_src/yaml_private.h src/yaml_private.h
    old new  
    2525yaml_strdup(const yaml_char_t *); 
    2626 
    2727/* 
    28  * Reader: Ensure that the buffer contains at least `length` characters. 
     28 * Reader: Ensure that the buffer contains at least `length` bytes. 
    2929 */ 
    3030 
    3131YAML_DECLARE(int) 
     
    237237 
    238238/* 
    239239 * Check if the character can be printed unescaped. 
     240 * Only correct if you know you are looking at valid UTF-8! 
    240241 */ 
    241242 
    242243#define IS_PRINTABLE_AT(string,offset)                                          \ 
     
    355356 
    356357/* 
    357358 * Determine the width of the character. 
     359 * Only correct if you know you are looking at valid UTF-8! 
    358360 */ 
    359361 
    360362#define WIDTH_AT(string,offset)                                                 \ 
     
    366368#define WIDTH(string)   WIDTH_AT((string),0) 
    367369 
    368370/* 
    369  * Move the string pointer to the next character. 
     371 * Move the string pointer to the next byte. 
    370372 */ 
    371373 
    372 #define MOVE(string)    ((string).pointer += WIDTH((string))) 
     374#define MOVE(string)    ((string).pointer++) 
     375 
     376#define MOVEN(string,n)  ((string).pointer += n) 
    373377 
    374378/* 
    375  * Copy a character and move the pointers of both strings. 
     379 * Copy a byte and move the pointers of both strings. 
    376380 */ 
    377381 
    378382#define COPY(string_a,string_b)                                                 \ 
    379     ((*(string_b).pointer & 0x80) == 0x00 ?                                     \ 
    380      (*((string_a).pointer++) = *((string_b).pointer++)) :                      \ 
    381      (*(string_b).pointer & 0xE0) == 0xC0 ?                                     \ 
    382      (*((string_a).pointer++) = *((string_b).pointer++),                        \ 
    383       *((string_a).pointer++) = *((string_b).pointer++)) :                      \ 
    384      (*(string_b).pointer & 0xF0) == 0xE0 ?                                     \ 
    385      (*((string_a).pointer++) = *((string_b).pointer++),                        \ 
    386       *((string_a).pointer++) = *((string_b).pointer++),                        \ 
    387       *((string_a).pointer++) = *((string_b).pointer++)) :                      \ 
    388      (*(string_b).pointer & 0xF8) == 0xF0 ?                                     \ 
    389      (*((string_a).pointer++) = *((string_b).pointer++),                        \ 
    390       *((string_a).pointer++) = *((string_b).pointer++),                        \ 
    391       *((string_a).pointer++) = *((string_b).pointer++),                        \ 
    392       *((string_a).pointer++) = *((string_b).pointer++)) : 0) 
     383     (*((string_a).pointer++) = *((string_b).pointer++)) 
     384 
     385#define COPYN(string_a,string_b,n)                                              \ 
     386  (memcpy(string_a.pointer, string_b.pointer, n),                               \ 
     387   string_a.pointer += n, string_b.pointer += n) 
    393388 
    394389/* 
    395390 * Stack and queue management.