Ignore:
Timestamp:
Apr 26, 2006, 12:22:31 PM (15 years ago)
Author:
Sam Hocevar
Message:
  • Fixed our buffer overflow in the ANSI parser by simply skipping control sequences longer than 100 characters.
  • Documented the escape sequence format.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcaca/trunk/cucul/import.c

    r891 r893  
    244244        if(buffer[i] == '\x1b' && buffer[i + 1] == '[')
    245245        {
    246             unsigned int argv[1024]; /* Should be enough. Will it be? */
    247             unsigned int argc = 0;
     246            unsigned int argc, argv[101];
    248247            unsigned int param, inter, final;
    249248
    250             /* Offset to parameter bytes */
     249        /* Compute offsets to parameter bytes, intermediate bytes and
     250         * to the final byte. Only the final byte is mandatory, there
     251         * can be zero of the others.
     252         *
     253         * +-----+------------------+---------------------+-----------------+
     254         * | CSI | parameter bytes  | intermediate bytes  |   final byte    |
     255         * |     |   0x30 - 0x3f    |    0x20 - 0x2f      |   0x40 - 0x7e   |
     256         * | ^[[ | 0123456789:;<=>? | SPC !"#$%&'()*+,-./ | azAZ@[\]^_`{|}~ |
     257         * +-----+------------------+---------------------+-----------------+
     258         */
    251259            param = 2;
    252260
    253             /* Offset to intermediate bytes: skip parameter bytes */
    254261            for(inter = param; i + inter < size; inter++)
    255262                if(buffer[i + inter] < 0x30 || buffer[i + inter] > 0x3f)
    256263                    break;
    257264
    258             /* Offset to final byte: skip intermediate bytes */
    259265            for(final = inter; i + final < size; final++)
    260266                if(buffer[i + final] < 0x20 || buffer[i + final] > 0x2f)
     
    266272            skip += final;
    267273
     274            /* Sanity checks */
    268275            if(param < inter && buffer[i + param] >= 0x3c)
    269276            {
     
    273280            }
    274281
    275             /* Parse parameter bytes, if any */
     282            if(final - param > 100)
     283                continue; /* Suspiciously long sequence, skip it */
     284
     285            /* ECMA-48 5.4.2: Parameter string format */
    276286            if(param < inter)
    277287            {
     
    287297            }
    288298
    289             /* Interpret final byte */
     299            /* Interpret final byte. The code representations are given in
     300             * ECMA-48 5.4: Control sequences, and the code definitions are
     301             * given in ECMA-48 8.3: Definition of control functions. */
    290302            switch(buffer[i + final])
    291303            {
    292             case 'f':
    293             case 'H':
     304            case 'f': /* CUP - Cursor Position */
     305            case 'H': /* HVP - Character And Line Position */
    294306                x = (argc > 1) ? argv[1] - 1 : 0;
    295307                y = (argc > 0) ? argv[0] - 1 : 0;
    296308                break;
    297             case 'A':
     309            case 'A': /* CUU - Cursor Up */
    298310                y -= argc ? argv[0] : 1;
    299311                if(y < 0)
    300312                    y = 0;
    301313                break;
    302             case 'B':
     314            case 'B': /* CUD - Cursor Down */
    303315                y += argc ? argv[0] : 1;
    304316                break;
    305             case 'C':
     317            case 'C': /* CUF - Cursor Right */
    306318                x += argc ? argv[0] : 1;
    307319                break;
    308             case 'D':
     320            case 'D': /* CUB - Cursor Left */
    309321                x -= argc ? argv[0] : 1;
    310322                if(x < 0)
    311323                    x = 0;
    312324                break;
    313             case 's':
     325            case 's': /* Private (save cursor position) */
    314326                save_x = x;
    315327                save_y = y;
    316328                break;
    317             case 'u':
     329            case 'u': /* Private (reload cursor positin) */
    318330                x = save_x;
    319331                y = save_y;
    320332                break;
    321             case 'J':
     333            case 'J': /* ED - Erase In Page */
    322334                if(argv[0] == 2)
    323335                    x = y = 0;
    324336                break;
    325             case 'K':
    326                 // CLEAR END OF LINE
     337            case 'K': /* EL - Erase In Line */
    327338                for(j = x; j < width; j++)
    328339                    _cucul_putchar32(cv, j, y, (uint32_t)' ');
    329340                x = width;
    330341                break;
    331             case 'm':
     342            case 'm': /* SGR - Select Graphic Rendition */
    332343                for(j = 0; j < argc; j++)
    333344                    manage_modifiers(argv[j], &fg, &bg,
Note: See TracChangeset for help on using the changeset viewer.