~jconti/ubuntu/oneiric/webkit/fix_doc_path

« back to all changes in this revision

Viewing changes to WebCore/css/CSSGrammar.y

  • Committer: Bazaar Package Importer
  • Author(s): Mike Hommey
  • Date: 2008-09-27 08:57:48 UTC
  • mfrom: (3.1.6 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080927085748-yhzld00w0rekp961
Tags: 1.0.1-4
WebCore/dom/Document.*, WebCore/loader/DocLoader.*: Avoid DoS via
crafted CSS import statements. Fixes: CVE-2008-3632. Closes: #499771.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
%{
2
2
 
3
3
/*
4
 
 *  This file is part of the KDE libraries
5
4
 *  Copyright (C) 2002-2003 Lars Knoll (knoll@kde.org)
6
 
 *  Copyright (C) 2004, 2005, 2006, 2007 Apple Inc.
 
5
 *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
7
6
 *  Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
 
7
 *  Copyright (C) 2008 Eric Seidel <eric@webkit.org>
8
8
 *
9
9
 *  This library is free software; you can redistribute it and/or
10
10
 *  modify it under the terms of the GNU Lesser General Public
18
18
 *
19
19
 *  You should have received a copy of the GNU Lesser General Public
20
20
 *  License along with this library; if not, write to the Free Software
21
 
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
21
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22
22
 *
23
23
 */
24
24
 
26
26
 
27
27
#include "CSSMediaRule.h"
28
28
#include "CSSParser.h"
29
 
#include "CSSPrimitiveValue.h"
30
 
#include "CSSRule.h"
31
29
#include "CSSRuleList.h"
32
30
#include "CSSSelector.h"
33
31
#include "CSSStyleSheet.h"
34
32
#include "Document.h"
35
33
#include "HTMLNames.h"
36
34
#include "MediaList.h"
37
 
#include "MediaQuery.h"
38
 
#include "MediaQueryExp.h"
39
 
#include "PlatformString.h"
40
35
#include <stdlib.h>
41
36
#include <string.h>
42
37
 
43
 
#if ENABLE(SVG)
44
 
#include "ksvgcssproperties.h"
45
 
#include "ksvgcssvalues.h"
46
 
#endif
47
 
 
48
38
using namespace WebCore;
49
39
using namespace HTMLNames;
50
40
 
51
 
// The following file defines the function
52
 
//     const struct props *findProp(const char *word, int len)
53
 
//
54
 
// with 'props->id' a CSS property in the range from CSS_PROP_MIN to
55
 
// (and including) CSS_PROP_TOTAL-1
56
 
 
57
 
#include "CSSPropertyNames.c"
58
 
#include "CSSValueKeywords.c"
59
 
 
60
 
namespace WebCore {
61
 
 
62
 
int getPropertyID(const char* tagStr, int len)
63
 
{
64
 
    DeprecatedString prop;
65
 
 
66
 
    if (len && tagStr[0] == '-') {
67
 
        prop = DeprecatedString(tagStr, len);
68
 
        if (prop.startsWith("-apple-")) {
69
 
            prop = "-webkit-" + prop.mid(7);
70
 
            tagStr = prop.ascii();
71
 
            len++;
72
 
        } else if (prop.startsWith("-khtml-")) {
73
 
            prop = "-webkit-" + prop.mid(7);
74
 
            len++;
75
 
            tagStr = prop.ascii();
76
 
        }
77
 
 
78
 
        // Honor the use of old-style opacity (for Safari 1.1).
79
 
        if (prop == "-webkit-opacity") {
80
 
            const char * const opacity = "opacity";
81
 
            tagStr = opacity;
82
 
            len = strlen(opacity);
83
 
        }
84
 
    }
85
 
 
86
 
    const struct props* propsPtr = findProp(tagStr, len);
87
 
    if (!propsPtr)
88
 
        return 0;
89
 
 
90
 
    return propsPtr->id;
91
 
}
92
 
 
93
 
} // namespace WebCore
94
 
 
95
 
static inline int getValueID(const char* tagStr, int len)
96
 
{
97
 
    DeprecatedString prop;
98
 
    if (len && tagStr[0] == '-') {
99
 
        prop = DeprecatedString(tagStr, len);
100
 
        if (prop.startsWith("-apple-")) {
101
 
            prop = "-webkit-" + prop.mid(7);
102
 
            tagStr = prop.ascii();
103
 
            len++;
104
 
        } else if (prop.startsWith("-khtml-")) {
105
 
            prop = "-webkit-" + prop.mid(7);
106
 
            len++;
107
 
            tagStr = prop.ascii();
108
 
        }
109
 
    }
110
 
 
111
 
    const struct css_value* val = findValue(tagStr, len);
112
 
    if (!val)
113
 
        return 0;
114
 
 
115
 
    return val->id;
116
 
}
117
 
 
118
41
#define YYENABLE_NLS 0
119
42
#define YYLTYPE_IS_TRIVIAL 1
120
43
#define YYMAXDEPTH 10000
121
44
#define YYDEBUG 0
 
45
 
 
46
// FIXME: Replace with %parse-param { CSSParser* parser } once we can depend on bison 2.x
122
47
#define YYPARSE_PARAM parser
 
48
#define YYLEX_PARAM parser
123
49
 
124
50
%}
125
51
 
126
52
%pure_parser
127
53
 
128
54
%union {
 
55
    bool boolean;
 
56
    char character;
 
57
    int integer;
 
58
    double number;
 
59
    ParseString string;
 
60
 
129
61
    CSSRule* rule;
 
62
    CSSRuleList* ruleList;
130
63
    CSSSelector* selector;
131
 
    bool ok;
132
 
    MediaList *mediaList;
133
 
    CSSMediaRule* mediaRule;
134
 
    CSSRuleList* ruleList;
135
 
    ParseString string;
136
 
    float val;
137
 
    int prop_id;
138
 
    int attribute;
139
64
    CSSSelector::Relation relation;
140
 
    bool b;
141
 
    int i;
142
 
    char tok;
 
65
    MediaList* mediaList;
 
66
    MediaQuery* mediaQuery;
 
67
    MediaQuery::Restrictor mediaQueryRestrictor;
 
68
    MediaQueryExp* mediaQueryExp;
143
69
    Value value;
144
70
    ValueList* valueList;
145
 
 
146
 
    MediaQuery* mediaQuery;
147
 
    MediaQueryExp* mediaQueryExp;
148
71
    Vector<MediaQueryExp*>* mediaQueryExpList;
149
 
    MediaQuery::Restrictor mediaQueryRestrictor;
150
72
}
151
73
 
152
74
%{
153
75
 
154
 
static inline int cssyyerror(const char*) { return 1; }
155
 
static int cssyylex(YYSTYPE* yylval) { return CSSParser::current()->lex(yylval); }
 
76
static inline int cssyyerror(const char*)
 
77
{
 
78
    return 1;
 
79
}
 
80
 
 
81
static int cssyylex(YYSTYPE* yylval, void* parser)
 
82
{
 
83
    return static_cast<CSSParser*>(parser)->lex(yylval);
 
84
}
156
85
 
157
86
%}
158
87
 
159
 
//%expect 37
 
88
%expect 42
160
89
 
161
90
%left UNIMPORTANT_TOK
162
91
 
169
98
%token CONTAINS
170
99
 
171
100
%token <string> STRING
172
 
 
173
101
%right <string> IDENT
 
102
%token <string> NTH
174
103
 
175
104
%nonassoc <string> HEX
176
105
%nonassoc <string> IDSEL
197
126
%token MEDIA_NOT
198
127
%token MEDIA_AND
199
128
 
200
 
%token <val> QEMS
201
 
%token <val> EMS
202
 
%token <val> EXS
203
 
%token <val> PXS
204
 
%token <val> CMS
205
 
%token <val> MMS
206
 
%token <val> INS
207
 
%token <val> PTS
208
 
%token <val> PCS
209
 
%token <val> DEGS
210
 
%token <val> RADS
211
 
%token <val> GRADS
212
 
%token <val> MSECS
213
 
%token <val> SECS
214
 
%token <val> HERZ
215
 
%token <val> KHERZ
 
129
%token <number> QEMS
 
130
%token <number> EMS
 
131
%token <number> EXS
 
132
%token <number> PXS
 
133
%token <number> CMS
 
134
%token <number> MMS
 
135
%token <number> INS
 
136
%token <number> PTS
 
137
%token <number> PCS
 
138
%token <number> DEGS
 
139
%token <number> RADS
 
140
%token <number> GRADS
 
141
%token <number> MSECS
 
142
%token <number> SECS
 
143
%token <number> HERZ
 
144
%token <number> KHERZ
216
145
%token <string> DIMEN
217
 
%token <val> PERCENTAGE
218
 
%token <val> FLOAT
219
 
%token <val> INTEGER
 
146
%token <number> PERCENTAGE
 
147
%token <number> FLOATTOKEN
 
148
%token <number> INTEGER
220
149
 
221
150
%token <string> URI
222
151
%token <string> FUNCTION
228
157
 
229
158
%type <rule> charset
230
159
%type <rule> ruleset
231
 
%type <rule> ruleset_or_import
 
160
%type <rule> valid_rule_or_import
232
161
%type <rule> media
233
162
%type <rule> import
234
163
%type <rule> page
237
166
%type <rule> invalid_at
238
167
%type <rule> invalid_import
239
168
%type <rule> rule
 
169
%type <rule> valid_rule
240
170
 
241
171
%type <string> maybe_ns_prefix
242
172
 
255
185
%type <valueList> maybe_media_value
256
186
%type <mediaQueryExp> media_query_exp
257
187
%type <mediaQueryExpList> media_query_exp_list
258
 
%type <mediaQueryExpList> maybe_media_query_exp_list
 
188
%type <mediaQueryExpList> maybe_and_media_query_exp_list
259
189
 
260
190
%type <ruleList> ruleset_list
261
191
 
262
 
%type <prop_id> property
 
192
%type <integer> property
263
193
 
264
194
%type <selector> specifier
265
195
%type <selector> specifier_list
266
196
%type <selector> simple_selector
267
197
%type <selector> selector
268
198
%type <selector> selector_list
 
199
%type <selector> selector_with_trailing_whitespace
269
200
%type <selector> class
270
201
%type <selector> attrib
271
202
%type <selector> pseudo
272
203
 
273
 
%type <ok> declaration_list
274
 
%type <ok> decl_list
275
 
%type <ok> declaration
276
 
 
277
 
%type <b> prio
278
 
 
279
 
%type <i> match
280
 
%type <i> unary_operator
281
 
%type <tok> operator
 
204
%type <boolean> declaration_list
 
205
%type <boolean> decl_list
 
206
%type <boolean> declaration
 
207
 
 
208
%type <boolean> prio
 
209
 
 
210
%type <integer> match
 
211
%type <integer> unary_operator
 
212
%type <character> operator
282
213
 
283
214
%type <valueList> expr
284
215
%type <value> term
298
229
  | webkit_mediaquery maybe_space
299
230
  ;
300
231
 
301
 
ruleset_or_import:
302
 
   ruleset |
303
 
   import
304
 
;
 
232
valid_rule_or_import:
 
233
    valid_rule
 
234
  | import
 
235
  ;
305
236
 
306
237
webkit_rule:
307
 
    WEBKIT_RULE_SYM '{' maybe_space ruleset_or_import maybe_space '}' {
308
 
        static_cast<CSSParser*>(parser)->rule = $4;
 
238
    WEBKIT_RULE_SYM '{' maybe_space valid_rule_or_import maybe_space '}' {
 
239
        static_cast<CSSParser*>(parser)->m_rule = $4;
309
240
    }
310
241
;
311
242
 
319
250
    WEBKIT_VALUE_SYM '{' maybe_space expr '}' {
320
251
        CSSParser* p = static_cast<CSSParser*>(parser);
321
252
        if ($4) {
322
 
            p->valueList = p->sinkFloatingValueList($4);
323
 
            int oldParsedProperties = p->numParsedProperties;
324
 
            if (!p->parseValue(p->id, p->important))
325
 
                p->rollbackLastProperties(p->numParsedProperties - oldParsedProperties);
326
 
            delete p->valueList;
327
 
            p->valueList = 0;
 
253
            p->m_valueList = p->sinkFloatingValueList($4);
 
254
            int oldParsedProperties = p->m_numParsedProperties;
 
255
            if (!p->parseValue(p->m_id, p->m_important))
 
256
                p->rollbackLastProperties(p->m_numParsedProperties - oldParsedProperties);
 
257
            delete p->m_valueList;
 
258
            p->m_valueList = 0;
328
259
        }
329
260
    }
330
261
;
332
263
webkit_mediaquery:
333
264
     WEBKIT_MEDIAQUERY_SYM WHITESPACE maybe_space media_query '}' {
334
265
         CSSParser* p = static_cast<CSSParser*>(parser);
335
 
         p->mediaQuery = p->sinkFloatingMediaQuery($4);
 
266
         p->m_mediaQuery = p->sinkFloatingMediaQuery($4);
336
267
     }
337
268
;
338
269
 
357
288
  CHARSET_SYM maybe_space STRING maybe_space ';' {
358
289
     CSSParser* p = static_cast<CSSParser*>(parser);
359
290
     $$ = static_cast<CSSParser*>(parser)->createCharsetRule($3);
360
 
     if ($$ && p->styleElement && p->styleElement->isCSSStyleSheet())
361
 
         p->styleElement->append($$);
 
291
     if ($$ && p->m_styleSheet)
 
292
         p->m_styleSheet->append($$);
362
293
  }
363
294
  | CHARSET_SYM error invalid_block {
364
295
  }
370
301
 /* empty */
371
302
 | import_list import maybe_sgml {
372
303
     CSSParser* p = static_cast<CSSParser*>(parser);
373
 
     if ($2 && p->styleElement && p->styleElement->isCSSStyleSheet())
374
 
         p->styleElement->append($2);
 
304
     if ($2 && p->m_styleSheet)
 
305
         p->m_styleSheet->append($2);
375
306
 }
376
307
 ;
377
308
 
384
315
   /* empty */
385
316
 | rule_list rule maybe_sgml {
386
317
     CSSParser* p = static_cast<CSSParser*>(parser);
387
 
     if ($2 && p->styleElement && p->styleElement->isCSSStyleSheet())
388
 
         p->styleElement->append($2);
 
318
     if ($2 && p->m_styleSheet)
 
319
         p->m_styleSheet->append($2);
389
320
 }
390
321
 ;
391
322
 
392
 
rule:
 
323
valid_rule:
393
324
    ruleset
394
325
  | media
395
326
  | page
396
327
  | font_face
 
328
  ;
 
329
 
 
330
rule:
 
331
    valid_rule
397
332
  | invalid_rule
398
333
  | invalid_at
399
334
  | invalid_import
400
 
    ;
 
335
  ;
401
336
 
402
337
import:
403
338
    IMPORT_SYM maybe_space string_or_uri maybe_space maybe_media_list ';' {
414
349
namespace:
415
350
NAMESPACE_SYM maybe_space maybe_ns_prefix string_or_uri maybe_space ';' {
416
351
    CSSParser* p = static_cast<CSSParser*>(parser);
417
 
    if (p->styleElement && p->styleElement->isCSSStyleSheet())
418
 
        static_cast<CSSStyleSheet*>(p->styleElement)->addNamespace(p, atomicString($3), atomicString($4));
 
352
    if (p->m_styleSheet)
 
353
        p->m_styleSheet->addNamespace(p, $3, $4);
419
354
}
420
355
| NAMESPACE_SYM error invalid_block
421
356
| NAMESPACE_SYM error ';'
447
382
    ;
448
383
 
449
384
media_query_exp:
450
 
    MEDIA_AND maybe_space '(' maybe_space media_feature maybe_space maybe_media_value ')' maybe_space {
451
 
        $5.lower();
452
 
        $$ = static_cast<CSSParser*>(parser)->createFloatingMediaQueryExp(atomicString($5), $7);
 
385
    '(' maybe_space media_feature maybe_space maybe_media_value ')' maybe_space {
 
386
        $3.lower();
 
387
        $$ = static_cast<CSSParser*>(parser)->createFloatingMediaQueryExp($3, $5);
453
388
    }
454
389
    ;
455
390
 
456
391
media_query_exp_list:
457
392
    media_query_exp {
458
 
      CSSParser* p = static_cast<CSSParser*>(parser);
459
 
      $$ = p->createFloatingMediaQueryExpList();
460
 
      $$->append(p->sinkFloatingMediaQueryExp($1));
 
393
        CSSParser* p = static_cast<CSSParser*>(parser);
 
394
        $$ = p->createFloatingMediaQueryExpList();
 
395
        $$->append(p->sinkFloatingMediaQueryExp($1));
461
396
    }
462
 
    | media_query_exp_list media_query_exp {
463
 
      $$ = $1;
464
 
      $$->append(static_cast<CSSParser*>(parser)->sinkFloatingMediaQueryExp($2));
 
397
    | media_query_exp_list maybe_space MEDIA_AND maybe_space media_query_exp {
 
398
        $$ = $1;
 
399
        $$->append(static_cast<CSSParser*>(parser)->sinkFloatingMediaQueryExp($5));
465
400
    }
466
401
    ;
467
402
 
468
 
maybe_media_query_exp_list:
 
403
maybe_and_media_query_exp_list:
469
404
    /*empty*/ {
470
405
        $$ = static_cast<CSSParser*>(parser)->createFloatingMediaQueryExpList();
471
406
    }
472
 
    | media_query_exp_list
 
407
    | MEDIA_AND maybe_space media_query_exp_list {
 
408
        $$ = $3;
 
409
    }
473
410
    ;
474
411
 
475
412
maybe_media_restrictor:
485
422
    ;
486
423
 
487
424
media_query:
488
 
    maybe_media_restrictor maybe_space medium maybe_media_query_exp_list {
 
425
    media_query_exp_list {
 
426
        CSSParser* p = static_cast<CSSParser*>(parser);
 
427
        $$ = p->createFloatingMediaQuery(p->sinkFloatingMediaQueryExpList($1));
 
428
    }
 
429
    |
 
430
    maybe_media_restrictor maybe_space medium maybe_and_media_query_exp_list {
489
431
        CSSParser* p = static_cast<CSSParser*>(parser);
490
432
        $3.lower();
491
 
        $$ = p->createFloatingMediaQuery($1, domString($3), p->sinkFloatingMediaQueryExpList($4));
 
433
        $$ = p->createFloatingMediaQuery($1, $3, p->sinkFloatingMediaQueryExpList($4));
492
434
    }
493
435
    ;
494
436
 
551
493
pseudo_page
552
494
  : ':' IDENT
553
495
  ;
554
 
 
555
 
font_face
556
 
  : FONT_FACE_SYM maybe_space
557
 
    '{' maybe_space declaration [ ';' maybe_space declaration ]* '}' maybe_space
558
 
  ;
559
496
*/
560
497
 
561
498
page:
568
505
    ;
569
506
 
570
507
font_face:
571
 
    FONT_FACE_SYM error invalid_block {
 
508
    FONT_FACE_SYM maybe_space
 
509
    '{' maybe_space declaration_list '}'  maybe_space {
 
510
        $$ = static_cast<CSSParser*>(parser)->createFontFaceRule();
 
511
    }
 
512
    | FONT_FACE_SYM error invalid_block {
572
513
      $$ = 0;
573
514
    }
574
 
  | FONT_FACE_SYM error ';' {
 
515
    | FONT_FACE_SYM error ';' {
575
516
      $$ = 0;
576
517
    }
577
518
;
580
521
    '+' maybe_space { $$ = CSSSelector::DirectAdjacent; }
581
522
  | '~' maybe_space { $$ = CSSSelector::IndirectAdjacent; }
582
523
  | '>' maybe_space { $$ = CSSSelector::Child; }
583
 
  | /* empty */ { $$ = CSSSelector::Descendant; }
584
524
  ;
585
525
 
586
526
unary_operator:
611
551
    }
612
552
   ;
613
553
 
 
554
selector_with_trailing_whitespace:
 
555
    selector WHITESPACE {
 
556
        $$ = $1;
 
557
    }
 
558
    ;
 
559
 
614
560
selector:
615
561
    simple_selector {
616
562
        $$ = $1;
617
563
    }
 
564
    | selector_with_trailing_whitespace
 
565
    {
 
566
        $$ = $1;
 
567
    }
 
568
    | selector_with_trailing_whitespace simple_selector
 
569
    {
 
570
        $$ = $2;
 
571
        if (!$1)
 
572
            $$ = 0;
 
573
        else if ($$) {
 
574
            CSSParser* p = static_cast<CSSParser*>(parser);
 
575
            CSSSelector* end = $$;
 
576
            while (end->m_tagHistory)
 
577
                end = end->m_tagHistory;
 
578
            end->m_relation = CSSSelector::Descendant;
 
579
            end->m_tagHistory = p->sinkFloatingSelector($1);
 
580
            if (Document* doc = p->document())
 
581
                doc->setUsesDescendantRules(true);
 
582
        }
 
583
    }
618
584
    | selector combinator simple_selector {
619
585
        $$ = $3;
620
586
        if (!$1)
626
592
                end = end->m_tagHistory;
627
593
            end->m_relation = $2;
628
594
            end->m_tagHistory = p->sinkFloatingSelector($1);
629
 
            if ($2 == CSSSelector::Descendant || $2 == CSSSelector::Child) {
 
595
            if ($2 == CSSSelector::Child) {
630
596
                if (Document* doc = p->document())
631
597
                    doc->setUsesDescendantRules(true);
632
598
            } else if ($2 == CSSSelector::DirectAdjacent || $2 == CSSSelector::IndirectAdjacent) {
645
611
    | '*' '|' { static UChar star = '*'; $$.characters = &star; $$.length = 1; }
646
612
    | IDENT '|' { $$ = $1; }
647
613
;
648
 
 
 
614
    
649
615
simple_selector:
650
 
    element_name maybe_space {
 
616
    element_name {
651
617
        CSSParser* p = static_cast<CSSParser*>(parser);
652
618
        $$ = p->createFloatingSelector();
653
 
        $$->m_tag = QualifiedName(nullAtom, atomicString($1), p->defaultNamespace);
 
619
        $$->m_tag = QualifiedName(nullAtom, $1, p->m_defaultNamespace);
654
620
    }
655
 
    | element_name specifier_list maybe_space {
 
621
    | element_name specifier_list {
656
622
        $$ = $2;
657
623
        if ($$) {
658
624
            CSSParser* p = static_cast<CSSParser*>(parser);
659
 
            $$->m_tag = QualifiedName(nullAtom, atomicString($1), p->defaultNamespace);
 
625
            $$->m_tag = QualifiedName(nullAtom, $1, p->m_defaultNamespace);
660
626
        }
661
627
    }
662
 
    | specifier_list maybe_space {
 
628
    | specifier_list {
663
629
        $$ = $1;
664
630
        CSSParser* p = static_cast<CSSParser*>(parser);
665
 
        if ($$ && p->defaultNamespace != starAtom)
666
 
            $$->m_tag = QualifiedName(nullAtom, starAtom, p->defaultNamespace);
 
631
        if ($$ && p->m_defaultNamespace != starAtom)
 
632
            $$->m_tag = QualifiedName(nullAtom, starAtom, p->m_defaultNamespace);
667
633
    }
668
 
    | namespace_selector element_name maybe_space {
669
 
        AtomicString namespacePrefix = atomicString($1);
 
634
    | namespace_selector element_name {
 
635
        AtomicString namespacePrefix = $1;
670
636
        CSSParser* p = static_cast<CSSParser*>(parser);
671
637
        $$ = p->createFloatingSelector();
672
 
        if (p->styleElement && p->styleElement->isCSSStyleSheet())
673
 
            $$->m_tag = QualifiedName(namespacePrefix,
674
 
                                    atomicString($2),
675
 
                                    static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
 
638
        if (p->m_styleSheet)
 
639
            $$->m_tag = QualifiedName(namespacePrefix, $2,
 
640
                                      p->m_styleSheet->determineNamespace(namespacePrefix));
676
641
        else // FIXME: Shouldn't this case be an error?
677
 
            $$->m_tag = QualifiedName(nullAtom, atomicString($2), p->defaultNamespace);
 
642
            $$->m_tag = QualifiedName(nullAtom, $2, p->m_defaultNamespace);
678
643
    }
679
 
    | namespace_selector element_name specifier_list maybe_space {
 
644
    | namespace_selector element_name specifier_list {
680
645
        $$ = $3;
681
646
        if ($$) {
682
 
            AtomicString namespacePrefix = atomicString($1);
 
647
            AtomicString namespacePrefix = $1;
683
648
            CSSParser* p = static_cast<CSSParser*>(parser);
684
 
            if (p->styleElement && p->styleElement->isCSSStyleSheet())
685
 
                $$->m_tag = QualifiedName(namespacePrefix,
686
 
                                          atomicString($2),
687
 
                                          static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
 
649
            if (p->m_styleSheet)
 
650
                $$->m_tag = QualifiedName(namespacePrefix, $2,
 
651
                                          p->m_styleSheet->determineNamespace(namespacePrefix));
688
652
            else // FIXME: Shouldn't this case be an error?
689
 
                $$->m_tag = QualifiedName(nullAtom, atomicString($2), p->defaultNamespace);
 
653
                $$->m_tag = QualifiedName(nullAtom, $2, p->m_defaultNamespace);
690
654
        }
691
655
    }
692
 
    | namespace_selector specifier_list maybe_space {
 
656
    | namespace_selector specifier_list {
693
657
        $$ = $2;
694
658
        if ($$) {
695
 
            AtomicString namespacePrefix = atomicString($1);
 
659
            AtomicString namespacePrefix = $1;
696
660
            CSSParser* p = static_cast<CSSParser*>(parser);
697
 
            if (p->styleElement && p->styleElement->isCSSStyleSheet())
698
 
                $$->m_tag = QualifiedName(namespacePrefix,
699
 
                                          starAtom,
700
 
                                          static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
 
661
            if (p->m_styleSheet)
 
662
                $$->m_tag = QualifiedName(namespacePrefix, starAtom,
 
663
                                          p->m_styleSheet->determineNamespace(namespacePrefix));
701
664
        }
702
665
    }
703
666
  ;
745
708
        CSSParser* p = static_cast<CSSParser*>(parser);
746
709
        $$ = p->createFloatingSelector();
747
710
        $$->m_match = CSSSelector::Id;
748
 
        if (!p->strict)
 
711
        if (!p->m_strict)
749
712
            $1.lower();
750
713
        $$->m_attr = idAttr;
751
 
        $$->m_value = atomicString($1);
 
714
        $$->m_value = $1;
752
715
    }
753
716
  | HEX {
754
717
        if ($1.characters[0] >= '0' && $1.characters[0] <= '9') {
757
720
            CSSParser* p = static_cast<CSSParser*>(parser);
758
721
            $$ = p->createFloatingSelector();
759
722
            $$->m_match = CSSSelector::Id;
760
 
            if (!p->strict)
 
723
            if (!p->m_strict)
761
724
                $1.lower();
762
725
            $$->m_attr = idAttr;
763
 
            $$->m_value = atomicString($1);
 
726
            $$->m_value = $1;
764
727
        }
765
728
    }
766
729
  | class
773
736
        CSSParser* p = static_cast<CSSParser*>(parser);
774
737
        $$ = p->createFloatingSelector();
775
738
        $$->m_match = CSSSelector::Class;
776
 
        if (!p->strict)
 
739
        if (!p->m_strict)
777
740
            $2.lower();
778
741
        $$->m_attr = classAttr;
779
 
        $$->m_value = atomicString($2);
 
742
        $$->m_value = $2;
780
743
    }
781
744
  ;
782
745
 
794
757
attrib:
795
758
    '[' maybe_space attr_name ']' {
796
759
        $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
797
 
        $$->m_attr = QualifiedName(nullAtom, atomicString($3), nullAtom);
 
760
        $$->m_attr = QualifiedName(nullAtom, $3, nullAtom);
798
761
        $$->m_match = CSSSelector::Set;
799
762
    }
800
763
    | '[' maybe_space attr_name match maybe_space ident_or_string maybe_space ']' {
801
764
        $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
802
 
        $$->m_attr = QualifiedName(nullAtom, atomicString($3), nullAtom);
 
765
        $$->m_attr = QualifiedName(nullAtom, $3, nullAtom);
803
766
        $$->m_match = (CSSSelector::Match)$4;
804
 
        $$->m_value = atomicString($6);
 
767
        $$->m_value = $6;
805
768
    }
806
769
    | '[' maybe_space namespace_selector attr_name ']' {
807
 
        AtomicString namespacePrefix = atomicString($3);
 
770
        AtomicString namespacePrefix = $3;
808
771
        CSSParser* p = static_cast<CSSParser*>(parser);
809
772
        $$ = p->createFloatingSelector();
810
 
        $$->m_attr = QualifiedName(namespacePrefix,
811
 
                                   atomicString($4),
812
 
                                   static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
 
773
        $$->m_attr = QualifiedName(namespacePrefix, $4,
 
774
                                   p->m_styleSheet->determineNamespace(namespacePrefix));
813
775
        $$->m_match = CSSSelector::Set;
814
776
    }
815
777
    | '[' maybe_space namespace_selector attr_name match maybe_space ident_or_string maybe_space ']' {
816
 
        AtomicString namespacePrefix = atomicString($3);
 
778
        AtomicString namespacePrefix = $3;
817
779
        CSSParser* p = static_cast<CSSParser*>(parser);
818
780
        $$ = p->createFloatingSelector();
819
 
        $$->m_attr = QualifiedName(namespacePrefix,
820
 
                                   atomicString($4),
821
 
                                   static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
 
781
        $$->m_attr = QualifiedName(namespacePrefix, $4,
 
782
                                   p->m_styleSheet->determineNamespace(namespacePrefix));
822
783
        $$->m_match = (CSSSelector::Match)$5;
823
 
        $$->m_value = atomicString($7);
 
784
        $$->m_value = $7;
824
785
    }
825
786
  ;
826
787
 
855
816
        $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
856
817
        $$->m_match = CSSSelector::PseudoClass;
857
818
        $2.lower();
858
 
        $$->m_value = atomicString($2);
 
819
        $$->m_value = $2;
859
820
        CSSSelector::PseudoType type = $$->pseudoType();
860
821
        if (type == CSSSelector::PseudoUnknown)
861
822
            $$ = 0;
862
823
        else if (type == CSSSelector::PseudoEmpty ||
863
 
                 type == CSSSelector::PseudoFirstChild) {
 
824
                 type == CSSSelector::PseudoFirstChild ||
 
825
                 type == CSSSelector::PseudoFirstOfType ||
 
826
                 type == CSSSelector::PseudoLastChild ||
 
827
                 type == CSSSelector::PseudoLastOfType ||
 
828
                 type == CSSSelector::PseudoOnlyChild ||
 
829
                 type == CSSSelector::PseudoOnlyOfType) {
864
830
            CSSParser* p = static_cast<CSSParser*>(parser);
865
831
            Document* doc = p->document();
866
832
            if (doc)
875
841
        $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
876
842
        $$->m_match = CSSSelector::PseudoElement;
877
843
        $3.lower();
878
 
        $$->m_value = atomicString($3);
 
844
        $$->m_value = $3;
879
845
        CSSSelector::PseudoType type = $$->pseudoType();
880
846
        if (type == CSSSelector::PseudoUnknown)
881
847
            $$ = 0;
885
851
                doc->setUsesFirstLineRules(true);
886
852
        }
887
853
    }
888
 
    // used by :lang
 
854
    // used by :nth-*(ax+b)
 
855
    | ':' FUNCTION NTH ')' {
 
856
        CSSParser *p = static_cast<CSSParser*>(parser);
 
857
        $$ = p->createFloatingSelector();
 
858
        $$->m_match = CSSSelector::PseudoClass;
 
859
        $$->m_argument = $3;
 
860
        $$->m_value = $2;
 
861
        CSSSelector::PseudoType type = $$->pseudoType();
 
862
        if (type == CSSSelector::PseudoUnknown)
 
863
            $$ = 0;
 
864
        else if (type == CSSSelector::PseudoNthChild ||
 
865
                 type == CSSSelector::PseudoNthOfType ||
 
866
                 type == CSSSelector::PseudoNthLastChild ||
 
867
                 type == CSSSelector::PseudoNthLastOfType) {
 
868
            if (p->document())
 
869
                p->document()->setUsesSiblingRules(true);
 
870
        }
 
871
    }
 
872
    // used by :nth-*
 
873
    | ':' FUNCTION INTEGER ')' {
 
874
        CSSParser *p = static_cast<CSSParser*>(parser);
 
875
        $$ = p->createFloatingSelector();
 
876
        $$->m_match = CSSSelector::PseudoClass;
 
877
        $$->m_argument = String::number($3);
 
878
        $$->m_value = $2;
 
879
        CSSSelector::PseudoType type = $$->pseudoType();
 
880
        if (type == CSSSelector::PseudoUnknown)
 
881
            $$ = 0;
 
882
        else if (type == CSSSelector::PseudoNthChild ||
 
883
                 type == CSSSelector::PseudoNthOfType ||
 
884
                 type == CSSSelector::PseudoNthLastChild ||
 
885
                 type == CSSSelector::PseudoNthLastOfType) {
 
886
            if (p->document())
 
887
                p->document()->setUsesSiblingRules(true);
 
888
        }
 
889
    }
 
890
    // used by :nth-*(odd/even) and :lang
889
891
    | ':' FUNCTION IDENT ')' {
890
 
        $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
 
892
        CSSParser *p = static_cast<CSSParser*>(parser);
 
893
        $$ = p->createFloatingSelector();
891
894
        $$->m_match = CSSSelector::PseudoClass;
892
 
        $$->m_argument = atomicString($3);
 
895
        $$->m_argument = $3;
893
896
        $2.lower();
894
 
        $$->m_value = atomicString($2);
895
 
        if ($$->pseudoType() == CSSSelector::PseudoUnknown)
 
897
        $$->m_value = $2;
 
898
        CSSSelector::PseudoType type = $$->pseudoType();
 
899
        if (type == CSSSelector::PseudoUnknown)
896
900
            $$ = 0;
 
901
        else if (type == CSSSelector::PseudoNthChild ||
 
902
                 type == CSSSelector::PseudoNthOfType ||
 
903
                 type == CSSSelector::PseudoNthLastChild ||
 
904
                 type == CSSSelector::PseudoNthLastOfType) {
 
905
            if (p->document())
 
906
                p->document()->setUsesSiblingRules(true);
 
907
        }
897
908
    }
898
909
    // used by :not
899
 
    | ':' NOTFUNCTION maybe_space simple_selector ')' {
 
910
    | ':' NOTFUNCTION maybe_space simple_selector maybe_space ')' {
900
911
        if (!$4)
901
912
            $$ = 0;
902
913
        else {
905
916
            $$->m_match = CSSSelector::PseudoClass;
906
917
            $$->m_simpleSelector = p->sinkFloatingSelector($4);
907
918
            $2.lower();
908
 
            $$->m_value = atomicString($2);
 
919
            $$->m_value = $2;
909
920
        }
910
921
    }
911
922
  ;
964
975
        $$ = false;
965
976
        CSSParser* p = static_cast<CSSParser*>(parser);
966
977
        if ($1 && $4) {
967
 
            p->valueList = p->sinkFloatingValueList($4);
968
 
            int oldParsedProperties = p->numParsedProperties;
 
978
            p->m_valueList = p->sinkFloatingValueList($4);
 
979
            int oldParsedProperties = p->m_numParsedProperties;
969
980
            $$ = p->parseValue($1, $5);
970
981
            if (!$$)
971
 
                p->rollbackLastProperties(p->numParsedProperties - oldParsedProperties);
972
 
            delete p->valueList;
973
 
            p->valueList = 0;
 
982
                p->rollbackLastProperties(p->m_numParsedProperties - oldParsedProperties);
 
983
            delete p->m_valueList;
 
984
            p->m_valueList = 0;
974
985
        }
975
986
    }
976
987
    |
994
1005
        /* div { font-family: } Just reduce away this property with no value. */
995
1006
        $$ = false;
996
1007
    }
 
1008
    |
 
1009
    property ':' maybe_space error {
 
1010
        /* if we come across rules with invalid values like this case: p { weight: *; }, just discard the rule */
 
1011
        $$ = false;
 
1012
    }
997
1013
  ;
998
1014
 
999
1015
property:
1000
1016
    IDENT maybe_space {
1001
 
        $1.lower();
1002
 
        DeprecatedString str = deprecatedString($1);
1003
 
        const char* s = str.ascii();
1004
 
        int l = str.length();
1005
 
        $$ = getPropertyID(s, l);
1006
 
#if ENABLE(SVG)
1007
 
        if ($$ == 0)
1008
 
            $$ = SVG::getSVGCSSPropertyID(s, l);
1009
 
#endif
 
1017
        $$ = cssPropertyID($1);
1010
1018
    }
1011
1019
  ;
1012
1020
 
1057
1065
  | unary_operator unary_term { $$ = $2; $$.fValue *= $1; }
1058
1066
  | STRING maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_STRING; }
1059
1067
  | IDENT maybe_space {
1060
 
      DeprecatedString str = deprecatedString($1);
1061
 
      $$.id = getValueID(str.lower().latin1(), str.length());
1062
 
#if ENABLE(SVG)
1063
 
      if ($$.id == 0)
1064
 
          $$.id = SVG::getSVGCSSValueID(str.lower().latin1(), str.length());
1065
 
#endif
 
1068
      $$.id = cssValueKeywordID($1);
1066
1069
      $$.unit = CSSPrimitiveValue::CSS_IDENT;
1067
1070
      $$.string = $1;
1068
1071
  }
1070
1073
  | DIMEN maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_DIMENSION }
1071
1074
  | unary_operator DIMEN maybe_space { $$.id = 0; $$.string = $2; $$.unit = CSSPrimitiveValue::CSS_DIMENSION }
1072
1075
  | URI maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_URI; }
1073
 
  | UNICODERANGE maybe_space { $$.id = 0; $$.iValue = 0; $$.unit = CSSPrimitiveValue::CSS_UNKNOWN;/* ### */ }
 
1076
  | UNICODERANGE maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_UNICODE_RANGE }
1074
1077
  | hexcolor { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_RGBCOLOR; }
1075
1078
  | '#' maybe_space { $$.id = 0; $$.string = ParseString(); $$.unit = CSSPrimitiveValue::CSS_RGBCOLOR; } /* Handle error case: "color: #;" */
1076
 
/* FIXME: according to the specs a function can have a unary_operator in front. I know no case where this makes sense */
 
1079
  /* FIXME: according to the specs a function can have a unary_operator in front. I know no case where this makes sense */
1077
1080
  | function {
1078
1081
      $$ = $1;
1079
1082
  }
 
1083
  | '%' maybe_space {} /* Handle width: %; */
1080
1084
  ;
1081
1085
 
1082
1086
unary_term:
1083
1087
  INTEGER maybe_space { $$.id = 0; $$.isInt = true; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; }
1084
 
  | FLOAT maybe_space { $$.id = 0; $$.isInt = false; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; }
 
1088
  | FLOATTOKEN maybe_space { $$.id = 0; $$.isInt = false; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; }
1085
1089
  | PERCENTAGE maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PERCENTAGE; }
1086
1090
  | PXS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PX; }
1087
1091
  | CMS maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_CM; }