@@ -356,94 +356,122 @@ static void HSL_to_RGB(css_fixed hue, css_fixed sat, css_fixed lit, uint8_t *r,
356356 *
357357 * It's up to the caller to reset the ctx if this fails.
358358 *
359+ * \param c Parsing context
359360 * \param vector Vector of tokens to process
360361 * \param ctx Pointer to vector iteration context
361- * \param colour_channels Number of colour channels to expect
362362 * \param result Pointer to location to receive result (AARRGGBB)
363363 * \return true on success, false on error.
364364 */
365365static bool parse_rgb (
366+ css_language * c ,
366367 const parserutils_vector * vector ,
367368 int32_t * ctx ,
368- int colour_channels ,
369369 uint32_t * result )
370370{
371371 const css_token * token ;
372372 css_token_type valid = CSS_TOKEN_NUMBER ;
373373 uint8_t r = 0 , g = 0 , b = 0 , a = 0xff ;
374374 uint8_t * components [4 ] = { & r , & g , & b , & a };
375+ bool legacy = false;
376+ bool had_none = false;
375377
376- for (int i = 0 ; i < colour_channels ; i ++ ) {
378+ for (int i = 0 ; i < 4 ; i ++ ) {
377379 uint8_t * component ;
378380 css_fixed num ;
379381 size_t consumed = 0 ;
380382 int32_t intval ;
381383 bool int_only ;
384+ bool match ;
382385
383386 component = components [i ];
384387
385388 consumeWhitespace (vector , ctx );
386389
387390 token = parserutils_vector_peek (vector , * ctx );
388- if (token == NULL || (token -> type !=
389- CSS_TOKEN_NUMBER &&
390- token -> type !=
391- CSS_TOKEN_PERCENTAGE ))
391+ if (token == NULL ) {
392392 return false;
393+ } else if (!legacy && token -> type == CSS_TOKEN_IDENT &&
394+ lwc_string_caseless_isequal (
395+ token -> idata , c -> strings [NONE ],
396+ & match ) == lwc_error_ok && match ) {
397+ had_none = true;
398+ } else {
399+ if (token -> type != CSS_TOKEN_NUMBER &&
400+ token -> type != CSS_TOKEN_PERCENTAGE ) {
401+ return false;
402+ }
393403
394- if (i == 0 )
395- valid = token -> type ;
396- else if (i < 3 && token -> type != valid )
397- return false;
404+ if (i == 0 ) {
405+ valid = token -> type ;
406+ } else if (legacy && i < 3 && token -> type != valid ) {
407+ return false;
408+ } else {
409+ valid = token -> type ;
410+ }
398411
399- /* The alpha channel may be a float */
400- if (i < 3 )
401- int_only = (valid == CSS_TOKEN_NUMBER );
402- else
403- int_only = false;
412+ /* The alpha channel may be a float */
413+ if (i < 3 ) {
414+ int_only = (valid == CSS_TOKEN_NUMBER );
415+ } else {
416+ int_only = false;
417+ }
404418
405- num = css__number_from_lwc_string (token -> idata ,
406- int_only , & consumed );
407- if (consumed != lwc_string_length (token -> idata ))
408- return false;
419+ num = css__number_from_lwc_string (token -> idata ,
420+ int_only , & consumed );
421+ if (consumed != lwc_string_length (token -> idata )) {
422+ return false;
423+ }
409424
410- if (valid == CSS_TOKEN_NUMBER ) {
411- if (i == 3 ) {
412- /* alpha channel */
425+ if (valid == CSS_TOKEN_NUMBER ) {
426+ if (i == 3 ) {
427+ /* alpha channel */
428+ intval = FIXTOINT (FMUL (num , F_255 ));
429+ } else {
430+ /* colour channels */
431+ intval = FIXTOINT (num );
432+ }
433+ } else {
413434 intval = FIXTOINT (
414- FMUL (num , F_255 ));
435+ FDIV (FMUL (num , F_255 ), F_100 ));
436+ }
437+
438+ if (intval > 255 ) {
439+ * component = 255 ;
440+ } else if (intval < 0 ) {
441+ * component = 0 ;
415442 } else {
416- /* colour channels */
417- intval = FIXTOINT (num );
443+ * component = intval ;
418444 }
419- } else {
420- intval = FIXTOINT (
421- FDIV (FMUL (num , F_255 ), F_100 ));
422445 }
423446
424- if (intval > 255 )
425- * component = 255 ;
426- else if (intval < 0 )
427- * component = 0 ;
428- else
429- * component = intval ;
430-
431447 parserutils_vector_iterate (vector , ctx );
432448
433449 consumeWhitespace (vector , ctx );
434450
435451 token = parserutils_vector_peek (vector , * ctx );
436- if (token == NULL )
452+ if (token == NULL ) {
437453 return false;
454+ }
455+
456+ if (i == 0 && tokenIsChar (token , ',' ) && !had_none ) {
457+ legacy = true;
458+ }
438459
439- if (i != (colour_channels - 1 ) &&
440- tokenIsChar (token , ',' )) {
460+ if (i >= 2 && tokenIsChar (token , ')' )) {
441461 parserutils_vector_iterate (vector , ctx );
442- } else if (i == (colour_channels - 1 ) &&
443- tokenIsChar (token , ')' )) {
462+ break ;
463+
464+ } else if (legacy ) {
465+ if (!tokenIsChar (token , ',' )) {
466+ return false;
467+ }
468+ parserutils_vector_iterate (vector , ctx );
469+
470+ } else if (i == 2 ) {
471+ if (!tokenIsChar (token , '/' )) {
472+ return false;
473+ }
444474 parserutils_vector_iterate (vector , ctx );
445- } else {
446- return false;
447475 }
448476 }
449477
@@ -699,7 +727,7 @@ css_error css__parse_colour_specifier(css_language *c,
699727 }
700728
701729 if (colour_channels == 3 || colour_channels == 4 ) {
702- if (!parse_rgb (vector , ctx , colour_channels , result )) {
730+ if (!parse_rgb (c , vector , ctx , result )) {
703731 goto invalid ;
704732 }
705733 } else if (colour_channels == 5 || colour_channels == 6 ) {
0 commit comments