18403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// Copyright (c) 2011, Mike Samuel 28403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// All rights reserved. 38403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// 48403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// Redistribution and use in source and binary forms, with or without 58403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// modification, are permitted provided that the following conditions 68403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// are met: 78403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// 88403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// Redistributions of source code must retain the above copyright 98403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// notice, this list of conditions and the following disclaimer. 108403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// Redistributions in binary form must reproduce the above copyright 118403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// notice, this list of conditions and the following disclaimer in the 128403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// documentation and/or other materials provided with the distribution. 138403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// Neither the name of the OWASP nor the names of its contributors may 148403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// be used to endorse or promote products derived from this software 158403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// without specific prior written permission. 168403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 178403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 188403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 198403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 208403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 218403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 228403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 238403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 248403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 258403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 268403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 278403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// POSSIBILITY OF SUCH DAMAGE. 288403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel 294e867904c8295537803c1c8a076e130df5674b58mikesamuelpackage org.owasp.html; 304e867904c8295537803c1c8a076e130df5674b58mikesamuel 314e867904c8295537803c1c8a076e130df5674b58mikesamuelimport java.util.List; 32b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel 33b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuelimport org.junit.Test; 344e867904c8295537803c1c8a076e130df5674b58mikesamuel 354e867904c8295537803c1c8a076e130df5674b58mikesamuelimport com.google.common.base.Joiner; 364e867904c8295537803c1c8a076e130df5674b58mikesamuelimport com.google.common.collect.Lists; 374e867904c8295537803c1c8a076e130df5674b58mikesamuel 384e867904c8295537803c1c8a076e130df5674b58mikesamuelimport junit.framework.TestCase; 394e867904c8295537803c1c8a076e130df5674b58mikesamuel 404e867904c8295537803c1c8a076e130df5674b58mikesamuelpublic class CssGrammarTest extends TestCase { 41b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel @Test 42b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel public static final void testLex() throws Exception { 43b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel CssTokens tokens = CssTokens.lex(Joiner.on('\n').join( 444e867904c8295537803c1c8a076e130df5674b58mikesamuel "/* A comment */", 454e867904c8295537803c1c8a076e130df5674b58mikesamuel "words with-dashes #hashes .dots. -and-leading-dashes", 464e867904c8295537803c1c8a076e130df5674b58mikesamuel "quantities: 3px 4ex -.5pt 12.5%", 47b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "punctuation: { ( } / , ;", 48b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "[ url( http://example.com )", 494e867904c8295537803c1c8a076e130df5674b58mikesamuel "rgb(255, 127, 127)", 50b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "'strings' \"oh \\\"my\" 'foo bar'", 514e867904c8295537803c1c8a076e130df5674b58mikesamuel "")); 524e867904c8295537803c1c8a076e130df5674b58mikesamuel 534e867904c8295537803c1c8a076e130df5674b58mikesamuel List<String> actualTokens = Lists.newArrayList(); 54b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel for (CssTokens.TokenIterator it = tokens.iterator(); it.hasNext();) { 55b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel CssTokens.TokenType type = it.type(); 56b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel String token = it.next(); 57b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel if (!" ".equals(token)) { 58b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel actualTokens.add(token + ":" + type.name()); 594e867904c8295537803c1c8a076e130df5674b58mikesamuel } 604e867904c8295537803c1c8a076e130df5674b58mikesamuel } 614e867904c8295537803c1c8a076e130df5674b58mikesamuel 624e867904c8295537803c1c8a076e130df5674b58mikesamuel assertEquals( 634e867904c8295537803c1c8a076e130df5674b58mikesamuel Joiner.on('\n').join( 64b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel // "/* A comment */", // Comments are elided. 65b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "words:IDENT", 66b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "with-dashes:IDENT", 67b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "#hashes:HASH_ID", 68b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel ".dots:DOT_IDENT", 69b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel ".:DELIM", 70b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "-and-leading-dashes:IDENT", 71b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "quantities:IDENT", 72b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "::COLON", 73b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "3px:DIMENSION", 74b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "4ex:DIMENSION", 75b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "-0.5pt:DIMENSION", 76b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "12.5%:PERCENTAGE", 77b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "punctuation:IDENT", 78b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "::COLON", 79b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "{:LEFT_CURLY", 80b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "(:LEFT_PAREN", // Explicit 81b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "):RIGHT_PAREN", // Implicit closing bracket to keep balance. 82b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "}:RIGHT_CURLY", 83b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "/:DELIM", 84b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel ",:COMMA", 85b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel ";:SEMICOLON", 86b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "[:LEFT_SQUARE", 87b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "url('http://example.com'):URL", 88b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "rgb(:FUNCTION", 89b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "255:NUMBER", 90b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel ",:COMMA", 91b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "127:NUMBER", 92b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel ",:COMMA", 93b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "127:NUMBER", 94b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "):RIGHT_PAREN", 95b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "'strings':STRING", 96b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "'oh \\22my':STRING", 97b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "'foo bar':STRING", 98b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel "]:RIGHT_SQUARE" 994e867904c8295537803c1c8a076e130df5674b58mikesamuel ), 1004e867904c8295537803c1c8a076e130df5674b58mikesamuel Joiner.on('\n').join(actualTokens)); 1014e867904c8295537803c1c8a076e130df5674b58mikesamuel } 1024e867904c8295537803c1c8a076e130df5674b58mikesamuel 103b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel @Test 104b600c3cd7edfb02d79c264fd83b1306e94053b7emikesamuel public static final void testCssContent() { 1054e867904c8295537803c1c8a076e130df5674b58mikesamuel assertEquals("", CssGrammar.cssContent("")); 1064e867904c8295537803c1c8a076e130df5674b58mikesamuel assertEquals("azimuth", CssGrammar.cssContent("\\61zimuth")); 1074e867904c8295537803c1c8a076e130df5674b58mikesamuel assertEquals("table-cell", CssGrammar.cssContent("t\\61\tble-cell")); 1084e867904c8295537803c1c8a076e130df5674b58mikesamuel assertEquals("foo", CssGrammar.cssContent("foo")); 1094e867904c8295537803c1c8a076e130df5674b58mikesamuel assertEquals("foo", CssGrammar.cssContent("'foo'")); 1104e867904c8295537803c1c8a076e130df5674b58mikesamuel assertEquals("foo", CssGrammar.cssContent("\"foo\"")); 1114e867904c8295537803c1c8a076e130df5674b58mikesamuel assertEquals("'", CssGrammar.cssContent("'")); 1124e867904c8295537803c1c8a076e130df5674b58mikesamuel assertEquals("\"", CssGrammar.cssContent("\"")); 1134e867904c8295537803c1c8a076e130df5674b58mikesamuel assertEquals("\"\"", CssGrammar.cssContent("\"\\22\\22\"")); 1144e867904c8295537803c1c8a076e130df5674b58mikesamuel assertEquals("\"\"", CssGrammar.cssContent("\"\\22 \\22\"")); 1154e867904c8295537803c1c8a076e130df5674b58mikesamuel assertEquals("\"\"", CssGrammar.cssContent("\\22\\22")); 1164e867904c8295537803c1c8a076e130df5674b58mikesamuel assertEquals("\\", CssGrammar.cssContent("'\\\\'")); 1174e867904c8295537803c1c8a076e130df5674b58mikesamuel assertEquals("\n", CssGrammar.cssContent("'\\a'")); 1184e867904c8295537803c1c8a076e130df5674b58mikesamuel } 1194e867904c8295537803c1c8a076e130df5674b58mikesamuel} 120