]> source.dussan.org Git - rspamd.git/commitdiff
[Project] Add css syntax (adopted from ebnf)
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 20 Jan 2021 21:17:32 +0000 (21:17 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 22 Jan 2021 15:58:05 +0000 (15:58 +0000)
src/libserver/css/css_syntax.rl [new file with mode: 0644]

diff --git a/src/libserver/css/css_syntax.rl b/src/libserver/css/css_syntax.rl
new file mode 100644 (file)
index 0000000..93da44b
--- /dev/null
@@ -0,0 +1,110 @@
+%%{
+  # CSS3 EBNF derived
+  machine css_syntax;
+
+  # Primitive Atoms
+  COMMENT = (
+    '/*' ( any )* :>> '*/'
+  );
+  QUOTED_STRING = ('"' ( [^"\\] | /\\./ )* "'");
+  BARE_URL_CHARS = ((0x21
+                                | 0x23..0x26
+                                | 0x2A..0xFF)+);
+  BARE_URL = BARE_URL_CHARS;
+  URL = 'url(' ( QUOTED_STRING | space* BARE_URL space* ) ')';
+  nonascii = [^0x00-0x7F];
+  nmstart = ([_a-zA-Z] | nonascii);
+  nmchar  = ([_a-zA-Z0-9] | 0x2D | nonascii);
+  name = nmchar+;
+  num  = ([0-9]+ | ([0-9]* '.' [0-9]+));
+  CRLF = "\r\n" | ("\r" [^\n]) | ([^\r] "\n");
+  IDENT = ([\-]? nmstart nmchar*);
+  ATTR = 'attr('  IDENT  ')';
+
+  DIMENSION = '-'? num space? ( 'ch' | 'cm' | 'em' | 'ex' | 'fr' | 'in' | 'mm' | 'pc' | 'pt' | 'px' | 'Q' | 'rem' | 'vh' | 'vmax' | 'vmin' | 'vw' | 'dpi' );
+  NUMBER = '-'? num;
+  HASH  = '#' name;
+  HEX  = '#' [0-9a-fA-F]{1,6};
+  PERCENTAGE = '-'? num '%';
+  INCLUDES = '~=';
+  DASHMATCH = '|=';
+  PREFIXMATCH = '^=';
+  SUFFIXMATCH = '$=';
+  SUBSTRINGMATCH = '*=';
+  PLUS = '+';
+  GREATER = '>';
+  COMMA = ',';
+  TILDE = '~';
+  S = space;
+
+  # Property name
+  property = ( QUOTED_STRING | IDENT );
+
+  # Values
+  important = space* '!' space* 'important';
+  expression = ( ( '+' | PERCENTAGE | URL | ATTR | HEX | '-' | DIMENSION  | NUMBER | QUOTED_STRING | IDENT | ',') S* )+;
+  functional_pseudo = (IDENT - ('attr'|'url')) '(' space* expression? ')';
+  value = ( URL | ATTR | PLUS | HEX | PERCENTAGE | '-' | DIMENSION | NUMBER | QUOTED_STRING | IDENT | functional_pseudo);
+  values = value (space value | '/' value )* ( space* ',' space* value (space value | '/' value )* )* important?;
+
+  # Declaration definition
+  declaration = (property space? ':'  (property ':')* space? values);
+
+  # Selectors
+  class = '.' IDENT;
+  element_name = IDENT;
+  namespace_prefix = ( IDENT | '*' )? '|';
+  type_selector = namespace_prefix? element_name;
+  universal = namespace_prefix? '*';
+  attrib = '[' space* namespace_prefix? IDENT space* ( ( PREFIXMATCH  | SUFFIXMATCH | SUBSTRINGMATCH | '=' | INCLUDES | DASHMATCH ) space* ( IDENT | QUOTED_STRING ) space* )? ']';
+  pseudo = ':' ':'? ( IDENT | functional_pseudo );
+  atrule = '@' IDENT;
+  mediaquery_selector = '(' declaration ')';
+  negation_arg = type_selector
+                 | universal
+                 | HASH
+                 | class
+                 | attrib
+                 | pseudo;
+  negation = 'NOT'|'not' space* negation_arg space* ')';
+  # Haha, so simple...
+  # there should be also mediaquery_selector but it makes grammar too large, so rip it off
+  simple_selector_sequence = ( type_selector | universal ) ( HASH | class | attrib | pseudo | negation | atrule )*
+               | ( HASH | class | attrib | pseudo | negation | atrule )+;
+  combinator = space* PLUS space*
+           | space* GREATER space*
+           | space* TILDE space*
+           | space+;
+  # Combine simple stuff and obtain just... an ordinary selector, bingo
+  selector = simple_selector_sequence ( combinator simple_selector_sequence )*;
+  # Multiple beasts
+  selectors_group = selector ( COMMENT? ',' space* selector )*;
+
+  # Rules
+  # This is mostly used stuff
+  rule = selectors_group space? "{" space*
+        (COMMENT? space* declaration ( space? ";" space? declaration?)* ";"? space?)* COMMENT* space* '}';
+  query_declaration = rule;
+
+  # Areas used in css
+  arearule = '@'('bottom-left'|'bottom-right'|'top-left'|'top-right');
+  areaquery = arearule space? '{' space* (COMMENT? space* declaration ( S? ';' S? declaration?)* ';'? space?)* COMMENT* space* '}';
+  # Printed media stuff, useless but we have to parse it :(
+  printcssrule = '@media print';
+  pagearea = ':'('left'|'right');
+  pagerule = '@page' space? pagearea?;
+  pagequery = pagerule space? '{' space* (areaquery| (COMMENT? space* declaration ( space? ';' space? declaration?)* ';'? S?)*) COMMENT* space* '}';
+  printcssquery = printcssrule S? '{' ( S? COMMENT* S? (pagequery| COMMENT|query_declaration) S*)* S? '}';
+  # Something that defines media
+  conditions =  ('and'|'screen'|'or'|'only'|'not'|'amzn-mobi'|'amzn-kf8'|'amzn-mobi7'|',');
+  mediarule = '@media' space conditions ( space? conditions| space?  mediaquery_selector )*;
+  mediaquery = mediarule space? '{' ( space? COMMENT* query_declaration)* S? '}';
+
+  simple_atrule  = ("@charset"|"@namespace") space+ QUOTED_STRING space* ";";
+
+  import_rule = "@import" space+ ( QUOTED_STRING | URL ) space* ";";
+
+  # Final css definition
+  css_style = space* ( (  rule | simple_atrule | import_rule | mediaquery | printcssquery | COMMENT) space* )*;
+
+}%%
\ No newline at end of file