Departamento de Engenharia Informática Faculdade de Ciências e Tecnologia Universidade de Coimbra Parser de Java para Motor de Análise de Segurança Dognædis Orientador DEI: Prof. Doutor Luís Miguel M. L. Macedo Orientador Dognædis: Eng. Hugo Miguel da Palma Trovão Luís Filipe Henriques Laranjeira [email protected] 28 de Junho de 2013 Resumo O presente documento representa o trabalho realizado por Luís Filipe Henriques Laranjeira, no âmbito da Dissertação de Mestrado em Engenharia Informática, no Departamento de Engenharia Informática, da Faculdade de Ciências e Tecnologia da Universidade de Coimbra. O propósito da dissertação consiste em criar um parser da linguagem Java, capaz de gerar uma árvore de sintaxe abstrata, a ser integrado no motor de análise estática de código, denominado CodeV[1], pertencente à empresa Dognædis, motor este que para além do suporte atual de deteção de vulnerabilidades na linguagem PHP, passará a suportar também a linguagem Java. Pretende-se nesta dissertação apresentar o estado da arte referente à temática em estudo, a arquitetura do sistema informático que sustenta o projeto e as várias fases de especificação, implementação e testes. Agradecimentos: Agradeço ao Engenheiro Hugo Trovão, por toda a amizade, apoio, incentivo e disponibilidade que sempre demonstrou. Agradeço ao Professor Doutor Luís Miguel M. L. Macedo por todo apoio e incentivo demonstrado. Agradeço a toda a equipa da Dognædis, por toda a ajuda disponibilizada e conhecimentos transmitidos. Dedicatória: Dedico este trabalho à minha família, aos meus amigos e à Dognædis, em especial ao meu Pai e à Tânia, por toda a compreensão, apoio, paciência e empenho demonstrado em todos os momentos. 2 Conteúdo 1 Introdução 1.1 Âmbito do Projeto . . . . 1.2 O Projeto . . . . . . . . . 1.3 Entidade Acolhedora . . 1.4 Restrições . . . . . . . . . 1.5 Estrutura do Documento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1 1 2 2 3 2 Planeamento 2.1 Metodologia . . . . . . . . . . . . . 2.2 Ferramentas Utilizadas . . . . . . . 2.2.1 Diagrama de Gantt . . . . . 2.2.2 Work Breakdown Structure 2.3 Identificação de Riscos . . . . . . . 2.4 Tarefas do Primeiro Semestre . . . 2.5 Tarefas do Segundo Semestre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 4 4 4 5 5 6 7 3 Estado da Arte 3.1 Parsers Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.1 Eclipse JDT Core Component . . . . . . . . . . . . . . . . 3.1.2 JRefactory . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.3 JavaParser . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.4 PMD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Comparação Parsers . . . . . . . . . . . . . . . . . . . . . . . . . 3.2.1 Testes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2.1.1 Configuração e Teste ao Java 1.6 . . . . . . . . 3.2.1.2 Teste ao Java 1.7 . . . . . . . . . . . . . . . . . 3.2.1.3 Teste a JSP . . . . . . . . . . . . . . . . . . . . . 3.2.1.4 Teste a Anotações, EJB e WS . . . . . . . . . . 3.2.1.5 Teste ao Performance e à Memória Utilizada 3.2.2 Resultados Obtidos . . . . . . . . . . . . . . . . . . . . . . 3.3 Estudo da Sustentabilidade do Desenvolvimento do Parser . . 3.4 Geradores de Parsers Existentes . . . . . . . . . . . . . . . . . . 3.4.1 YACC / Bison . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.2 JavaCC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.3 ANTLR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.4 Gold . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.5 Comparação e Seleção de Geradores de Parsers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 9 9 10 10 11 11 11 11 12 12 12 12 13 14 15 15 16 16 17 17 . . . . . . . . . . . . . . . . . . . . . . . . . I Luís Laranjeira - PJMAS 3.6 Aplicações Concorrentes ao CodeV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 4 Análise de Requisitos 4.1 Requisitos Funcionais . . . . . . . . . . . . . . . . . . . . . . . . . . 4.1.1 Parsing da Linguagem Comum Java . . . . . . . . . . . . . 4.1.2 Parsing Código Fonte Java e declarações XML nas JSP 4.1.3 Alteração aos Ciclos for na AST . . . . . . . . . . . . . . . 4.1.4 Extensão de Anotações . . . . . . . . . . . . . . . . . . . . 4.1.5 Extensão Múltiplos Exceptions nos Catch do JDK 1.7 . . 4.1.6 Alterações à AST nas JSP . . . . . . . . . . . . . . . . . . . 4.2 Requisitos Não Funcionais . . . . . . . . . . . . . . . . . . . . . . . 4.2.1 AST Gerada Compatível com a Plataforma Existente . . 4.2.2 Tempo de Execução . . . . . . . . . . . . . . . . . . . . . . . 4.2.3 Tamanho de Memória Usada . . . . . . . . . . . . . . . . . 4.2.4 Datas Definidas para Entregas . . . . . . . . . . . . . . . 4.3 Classificação dos Requisitos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 19 19 20 21 21 21 21 22 22 22 22 23 23 5 Definição da Aplicação 5.1 Arquitetura do Sistema . . . . . . . . . . . . . . . . . 5.1.1 Visão Geral . . . . . . . . . . . . . . . . . . . 5.1.2 Visão Detalhada do Parser . . . . . . . . . . 5.2 Gramática do Parser . . . . . . . . . . . . . . . . . . 5.2.1 Construção da Gramática . . . . . . . . . . . 5.2.2 Expressões Regulares . . . . . . . . . . . . . 5.2.2.1 Exemplo 1: ASTRoot . . . . . . . . 5.2.2.2 Exemplo 2: Statement . . . . . . . 5.2.2.3 Exemplo 3: AssignmentExpression 5.3 Parsing do Código . . . . . . . . . . . . . . . . . . . . 5.3.1 Top-Down Parsing . . . . . . . . . . . . . . . 5.3.2 Exemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 24 24 25 26 27 27 28 28 28 29 29 29 6 Implementação 6.1 Estados Lexicais . . . . . . . . . . . . . . . . . . . . . . . 6.2 Alteração dos Ciclos for na AST . . . . . . . . . . . . . 6.3 Extensão de Anotações . . . . . . . . . . . . . . . . . . . 6.4 Extensão Múltiplos Exceptions nos Catch do JDK 1.7 6.5 Alterações à AST nas JSP . . . . . . . . . . . . . . . . . 6.5.1 GetProperty . . . . . . . . . . . . . . . . . . . . . 6.5.2 SetProperty . . . . . . . . . . . . . . . . . . . . . 6.5.3 Beans . . . . . . . . . . . . . . . . . . . . . . . . . 6.5.4 Include e Forward . . . . . . . . . . . . . . . . . 6.6 Melhorias à Performance do Parser . . . . . . . . . . . 6.7 Iterações de Desenvolvimento . . . . . . . . . . . . . . . 6.7.1 Iteração 1 . . . . . . . . . . . . . . . . . . . . . . . 6.7.2 Iteração 2 . . . . . . . . . . . . . . . . . . . . . . . 6.7.3 Iteração 3 . . . . . . . . . . . . . . . . . . . . . . . 6.7.4 Iteração 4 . . . . . . . . . . . . . . . . . . . . . . . 6.7.5 Iteração 5 . . . . . . . . . . . . . . . . . . . . . . . 6.7.6 Iteração 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 31 33 35 35 36 36 37 39 40 41 43 43 43 43 44 44 44 II . . . . . . . . . . . . Luís Laranjeira - PJMAS 7 Controlo de Qualidade 7.1 Abordagem . . . . . . . . . . . . . . . . . . . . . . . . . 7.2 Tipos de Testes . . . . . . . . . . . . . . . . . . . . . . . 7.2.1 Testes às Funcionalidades . . . . . . . . . . . 7.2.2 Testes à Performance e Memória . . . . . . . 7.2.3 Testes de Integração com o CodeV . . . . . . 7.3 Especificação do Ambiente e da Máquina de Testes 7.4 Resultados Obtidos . . . . . . . . . . . . . . . . . . . . 7.4.1 Testes às Funcionalidades . . . . . . . . . . . 7.4.2 Testes ao parsing com Projetos . . . . . . . . 7.4.3 Testes à Performance e Memória . . . . . . . 7.4.4 Testes de Integração com o CodeV . . . . . . 7.5 Discussão dos Resultados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 45 45 45 47 47 48 48 49 49 50 50 51 8 Conclusão 52 8.1 Conclusão da Dissertação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 8.2 Reflexões Sobre o Desenrolar dos Trabalhos . . . . . . . . . . . . . . . . . . . . . . . 53 8.3 Futuro da Aplicação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 I Apêndices 56 A Diagrama de Gantt A.1 Diagrama de Gantt do Primeiro Semestre . . . . . . . . . . . . . . . . . . . . . . . . A.2 Diagrama de Gantt do Segundo Semestre (Plano Inicial) . . . . . . . . . . . . . . . A.3 Diagrama de Gantt do Segundo Semestre . . . . . . . . . . . . . . . . . . . . . . . . i ii iii iv B Work Breakdown Structure B.1 WBS Referente ao Primeiro Semestre . . . . . . . . . . . . . . . . . . . . . . . . . . . B.2 WBS Referente ao Segundo Semestre . . . . . . . . . . . . . . . . . . . . . . . . . . . v vi vii C Estimação de Tarefas, Segundo Semestre viii D Testes Performance e Memória E Aplicações Concorrentes ao CodeV E.1 Veracode: Static Analysis Tool . E.2 CodeSecure . . . . . . . . . . . . . E.3 Checkmarx Static code analysis E.4 IBM Security AppScan Source . xi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiv . xiv . xiv . xiv . xv F Gramática do Parser G Testes G.1 Testes G.1.1 G.1.2 G.1.3 G.1.4 G.1.5 xvi às Funcionalidades . . . . . . . . . . . . . . . . . . . . . . . Testes à Linguagem Java . . . . . . . . . . . . . . . . . . . Testes às JSP . . . . . . . . . . . . . . . . . . . . . . . . . . Testes à alteração de Ciclos . . . . . . . . . . . . . . . . . Testes à Expansão de Múltiplas Exceções nos Try-Catch Testes às Alterações aos nós da AST nas JSP . . . . . . III . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxvii xxviii xxviii lvii lxviii lxxii lxxv Luís Laranjeira - PJMAS G.2 Testes às Funcionalidades, Parsing de Projetos . . . . . . . . . . . . . . . . . . . . . lxxx G.3 Testes de Integração . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . lxxxiv IV Lista de Figuras 5.1 5.2 5.3 5.4 Visão Global da Arquitetura da Aplicação. . . . . . Diagrama de estados representativo da análise de Árvore resultante da expressão “int a = 4 + 5 ;” . Ordem em que os nós são selecionados/criados . . . . . . 25 26 29 30 6.1 Estados Lexicais do Parser e Transições. . . . . . . . . . . . . . . . . . . . . . . . . . 32 A.1 Diagrama de Gantt referente às tarefas do primeiro semestre. . . . . . . . . . . . . A.2 Diagrama de Gantt referente às tarefas do segundo semestre (plano inicial). . . . A.3 Diagrama de Gantt referente às tarefas do segundo semestre. . . . . . . . . . . . . ii iii iv B.1 WBS referente às tarefas do primeiro semestre. . . . . . . . . . . . . . . . . . . . . . B.2 WBS referente às tarefas do segundo semestre. . . . . . . . . . . . . . . . . . . . . . vi vii V . . . . . . . . um projeto. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lista de Tabelas 2.1 2.2 2.3 Tabela Auxiliar do Diagrama de Gantt do Primeiro Semestre. . . . . . . . . . . . . Tabela Auxiliar do Diagrama de Gantt do Segundo Semestre. . . . . . . . . . . . . Tabela da estimação geral do PJMAS, 2º semestre. . . . . . . . . . . . . . . . . . . . 3.1 3.2 3.3 3.4 3.5 Funcionalidades dos parsers analisados e do apresentado na dissertação. . Resultados aos testes de performance e memória utilizada. . . . . . . . . . . . Tabela representativa das vantagens de cada uma das opções possíveis. . . Tabela representativa das desvantagens de cada uma das opções possíveis. Tabela de comparação de geradores de parsers . . . . . . . . . . . . . . . . . . . . . . . 13 14 14 15 17 4.1 Tabela classificação dos requisitos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 5.1 Expressões Regulares Utilizadas na Gramática . . . . . . . . . . . . . . . . . . . . . 27 6.1 6.2 Comparação entre tempo de parsing com alterações e sem alterações aos ciclos . Comparação entre performance e memória utilizada antes e depois dos melhoramentos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 7.1 7.2 7.3 7.4 7.5 7.6 7.7 Modelo para testes às funcionalidades. . . . . . . . . . . . Exemplar de teste de integração. . . . . . . . . . . . . . . . Especificações da máquina utilizada para testes . . . . . Resultado da Validação das Funcionalidades. . . . . . . . Resumo resultados parsing a projetos. . . . . . . . . . . . Resumo resultados obtidos ao performance e memória do Comparação com outros Parsers analisados. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 48 48 49 50 50 51 C.1 C.2 C.3 C.4 Tabela do esforço de cada tarefa do PJMAS, 2º Semestre. . . . . . . Tabela do esforço geral do PJMAS, 2º semestre. . . . . . . . . . . . . Tabela auxiliar no cálculo do esforço. . . . . . . . . . . . . . . . . . . . Variação do tempo estimado conforme a percentagem de confiança. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ix ix ix x . . . . . . . . . . . . . . . . . . . . . . . . . parser. . . . . . . . . . . . . . . . . . . . . . . 6 7 8 42 D.1 Tempo de execução para cada teste, com ficheiro de 11080 linhas de código. . . . xii D.2 Memória utilizada em cada teste, com ficheiro de 11080 linhas de código. . . . . . xiii VI Glossário aplicação standalone É uma aplicação auto-suficiente que não necessita de software de terceiros. backtracking Técnica refinada da pesquisa exaustiva, em que todas as opções são analisadas até encontrar a solução desejada. bottom-up No parsing bottom-up a criação da árvore de parsing inicia-se nas folhas (símbolos terminais), gerando de seguida todos os nós até à raiz. CodeV Motor de análise estática de código da Dognædis, capaz de detetar vulnerabilidades no código fonte analisado. debug Processo de pesquisa de erros durante a execução de uma determinada aplicação. default Valor atribuído a determinada propriedade caso esta não seja especificada. framework Conjunto de ferramentas que promove a abstração entre vários projetos de modo a fornecer uma funcionalidade genérica. parser É um software capaz de subdividir uma dada entrada (input) em secções mais pequenas para que outro programa possa atuar sobre elas. plugin Ferramenta que estende as funcionalidades de uma determinada aplicação. refactoring É uma “técnica” disciplinada que permite a reestruturação do corpo de um código fonte já existente, sendo alterada a sua estrutura interna do código sem modificar o seu comportamento externo. VII Luís Laranjeira - PJMAS reserved tokens São as palavras/símbolos predefinidos da linguagem de programação em questão, que estão reservados para funções especificas e não podem por isso ser definidos como variáveis, objetos ou classes. top-down No parsing top-down a árvore de parsing é criada a partir da raiz, expandindo os nós até às folhas (símbolos terminais). árvore de sintaxe abstrata É uma representação em árvore da estrutura sintática de um ficheiro de código fonte de uma determinada linguagem. VIII Acrónimos ANTLR ANother Tool for Language Recognition API Application Programming Interface AST Abstract Syntax Tree BNF Backus–Naur Form BSD Berkeley Software Distribution CPU Central processing unit CSIRT Computer Security Incident Response Team DFA Deterministic Finite Automaton EBNF Extended Backus–Naur Form ECTS European Credit Transfer and Accumulation System EJB Enterprise JavaBeans EPL Eclipse Public License FTP File Transfer Protocol GNU GPL General Public License HTML HyperText Markup Language IDE Integrated Development Environment JavaCC Java Compiler Compiler JavaEE/J2EE Java Enterprise Edition JAXB Java Architecture for XML Binding JDK Java Development Kit JDT Java Development Tools IX Luís Laranjeira - PJMAS JMS Java Message Service JPA Java Persistence API JSF JavaServer Faces JSP Java Server Pages JVM Java Virtual Machine LALR Look-Ahead Left-to-right Right derivation parsing LL Left Linear parsing LR Left-to-right Right-derivation parsing MVC Model-View-Controller OWASP The Open Web Application Security Project PHP PHP: Hypertext Preprocessor PJMAS Parser de Java para Motor de Análise de Segurança SaaS Software-as-a-Service SOA Service-Oriented Architecture UC Universidade de Coimbra WBS Work Breakdown Structure WS Web Service XML eXtensible Markup Language XSL eXtensible Stylesheet Language XSLT eXtensible Stylesheet Language Transformations XSS Cross Site Scripting YACC Yet Another Compiler Compiler X Capítulo 1 Introdução O presente documento representa a dissertação elaborada no âmbito do estágio de Mestrado de Engenharia Informática do Departamento de Engenharia Informática da Universidade de Coimbra. O estágio consiste no desenvolvimento do projeto Parser de Java para Motor de Análise de Segurança (PJMAS), sendo a sua duração de dois semestres. No primeiro semestre foi delineado o planeamento do projeto, identificadas soluções já existentes e definidos os requisitos necessários para a implementação. O segundo semestre foi essencialmente dedicado à implementação e validação das funcionalidades do projeto. 1.1 Âmbito do Projeto A Internet é um meio de comunicação cada vez mais global, em que o número de aplicações web cresce exponencialmente e onde estão armazenados cada vez mais dados de cidadãos e instituições. Com tal crescimento e a importância que este particular meio tem na atualidade não é de admirar que os ataques e tentativas de furto a tal informação acompanhem e cresçam igualmente. Tal como a segurança tenta manter “segura” a informação, os “piratas informáticos” descobrem novas vulnerabilidades, estando sempre à procura de novas metodologias e ferramentas que usam em novos ataques sucessivos. Por estes motivos, a segurança da informação, é um elemento cada vez mais importante na Internet. Todos os dias existem roubos, interseções e adulterações de informação através de vulnerabilidades existentes, sendo que, grande parte dessas vulnerabilidades existem devido a falhas no código fonte da aplicação. O CodeV é uma aplicação criada pela empresa Dognædis que realiza uma análise automática de código fonte para detetar vulnerabilidades de segurança com foco em aplicações web, tentando aumentar a segurança das mesmas ao máximo. No momento, o CodeV já está em funcionamento, suportando para já a linguagem PHP: Hypertext Preprocessor (PHP). 1.2 O Projeto Um parser é um software capaz de subdividir uma dada entrada (input) em secções mais pequenas para que outro programa possa atuar sobre elas. Através das secções é possível gerar uma Abstract Syntax Tree (AST), em que os nós da árvore representam ocorrências no código fonte. 1 Luís Laranjeira - PJMAS O objetivo do projeto foi criar um parser para a linguagem Java. O autor decidiu focarse principalmente no Java Enterprise Edition (JavaEE/J2EE)[2], versão do Java que se foca principalmente em aplicações web, nomeadamente: Java Server Pages (JSP), servlets, beans, Enterprise JavaBeans (EJB), Java Persistence API (JPA) entre outros. Pretende-se através do parser gerar uma AST que vá de encontro ao esperado pelo motor de análise de segurança existente, de modo a que este passe e suportar as aplicações com os serviços acima referidos, aumentando, desta forma, o leque de linguagens suportadas pelo CodeV e, consequentemente, a segurança das aplicações de todos os utilizadores que queiram usar a aplicação. 1.3 Entidade Acolhedora A Dognædis é uma empresa resultante da união de duas equipas: um núcleo de investigadores do CERT-IPN e investigadores da Universidade de Coimbra. O CERT-IPN, criado no seio do Instituto Pedro Nunes, era uma equipa Computer Security Incident Response Team (CSIRT), que tinha como missão cultivar e implementar uma atitude de segurança pró-ativa na comunidade envolvente, incentivar o alargamento e a criação de comunidades portuguesas ligadas à segurança de informação, ser uma entidade de referência internacional, detentora e coletora de informação sobre segurança, e ser referência no mercado nacional de segurança de informação, assumindo como função primordial a execução, coordenação e suporte à resposta a incidentes de segurança existentes no seu âmbito de ação. A empresa presta serviços de Software Assurance, disponibilizando garantias de segurança e robustez para software, serviços de Business Continuity Support, através do apoio e garantia da continuidade de negócio por meio de capacidades de deteção, prevenção, mitigação e resolução de eventos de segurança, e serviços de auditoria e consultoria de segurança. Ao longo do seu curto tempo de existência, a Dognædis foi distinguida já com diversos prémios, designadamente: o “Prémio Coimbra Inovação Parque”, no âmbito do Concurso Arrisca Coimbra 2010. Já no inicio de 2012 arrecadou mais dois prémios, “Melhor Empresa Start-Up Nacional” na Gala do Empreendedorismo em Ciência e Tecnologia promovido pela TecParques e, com o produto CodeV[1], o prémio BES Inovação 2011 na área de Tecnologia [3]. A missão da Dognædis é estar na vanguarda das tecnologias de segurança, trazendo segurança de informação a organizações e indivíduos, através da excelência em soluções inovadoras. Com o projeto PJMAS, objetivo deste estágio/dissertação, a Dognædis continuará a evoluir positivamente, dando continuidade à sua missão e filosofia de modo a criar mecanismos capazes de aumentar a segurança nas aplicações web. 1.4 Restrições O projeto tinha, desde logo, algumas restrições impostas pela Dognæadis. Seguindo as regras da empresa, a ferramenta selecionada para construir o parser tinha que possuir uma licença de uso gratuita. Visto o sistema operativo utilizado na entidade acolhedora ser uma distribuição Linux/Unix, a ferramenta tinha que ser igualmente compatível com o mesmo. Como referido anteriormente, já existia um parser de uma outra linguagem e um motor de análise estática de código a funcionar, sendo necessário que o novo parser funcionasse em conjunto com os mesmos, reaproveitando classes já existentes de modo a ter uma menor complexidade e reaproveitamento de código, podendo no entanto serem adicionadas novas classes e/ou novos atributos, caso fosse mesmo necessário. Esta condição implicava que o parser a construir utilizasse, também, a mesma linguagem, ou seja, Java. 2 Luís Laranjeira - PJMAS 1.5 Estrutura do Documento Com o intuito de facilitar a leitura e compreensão desta dissertação, o autor dividiu-a em 8 capítulos distintos. No primeiro capítulo é efetuada a introdução ao projeto na sua globalidade. É identificado o seu âmbito, os objetivos e é apresentada a entidade acolhedora, fornecendo assim ao leitor uma primeira noção do que se pretende desenvolver e enquadrando-o com o projeto. São apresentadas, ainda, as restrições existentes ao desenvolvimento do presente projeto que, obrigatoriamente, foram tidas em linha de conta durante o presente estágio/dissertação. No segundo capítulo é apresentado o planeamento das tarefas realizadas no primeiro semestre e no segundo semestre. É, também, efetuado um levantamento dos riscos que poderiam ocorrer durante a implementação do projeto. Já no terceiro capítulo são analisados outros parsers Java já existentes e suas funcionalidades. É também efetuada uma análise às ferramentas necessárias para a construção do parser. É, ainda, selecionado o gerador de parsers para o projeto e é feita uma breve análise a outras aplicações concorrentes ao CodeV. O quarto capítulo apresenta os requisitos funcionais e requisitos não funcionais definidos para o projeto. É apresentada, ainda, uma classificação para as funcionalidades definidas para implementar no projeto. No quinto capítulo é abordada a definição da aplicação e especificada a arquitetura do sistema, quer no seu modo geral (funcionamento do CodeV), quer a nível mais especifico (parser desenvolvido). São apresentados excertos da gramática de modo a garantir uma compreensão integral da gramática completa que segue, em anexo, no presente relatório. No sexto capítulo são apresentadas todas as iterações de desenvolvimento efetuadas e as funcionalidades implementadas em cada iteração. São ainda apresentadas e explicadas especificações do parser desenvolvido, bem como alguns exemplos de alterações efetuadas na AST e melhoramentos ao parser implementados pelo autor. O sétimo capítulo contém os todos os testes realizados para validação de funcionalidades e do parser. São apresentados os resultados obtidos e uma análise aos mesmos. Por fim, no oitavo e último capítulo é efetuada uma reflexão sobre o trabalho desenvolvido ao longo do primeiro semestre, perspetivando, também, o trabalho futuro possível de desenvolver, com base no trabalho efetuado. 3 Capítulo 2 Planeamento Neste capítulo são apresentadas as metas definidas para o projeto PJMAS, bem como a sua priorização e possíveis riscos necessários a ter em consideração durante o desenvolvimento do projeto referido. 2.1 Metodologia A metodologia de trabalho adotada foi o desenvolvimento ágil. Foi definido que, sempre que possível, seriam realizados ciclos de duas semanas. A razão do espaço temporal atribuído, devese ao facto de que, esses ciclos, se fossem demasiado grandes seria mais complicado situa-los no tempo e tornaria a gestão de tarefas mais complexa. Em caso de ciclos menores, haveria lugar a tarefas mais pequenas, o que faria com que o número destas aumentasse, tornando desta forma a gestão de trabalhos mais complexa. Estes ciclos de trabalho iniciam-se sempre com dois dias reservados para revisão e documentação do trabalho realizado e do trabalho a realizar, procurando sempre despistar, previamente, possíveis desvios ao plano de trabalhos. Esta tarefa é acompanhada pelo orientador da empresa validando o trabalho realizado e perspetivando o seguinte. É importante ainda referir, que estes ciclos de desenvolvimento foram validados pelo orientador da empresa, uma vez que como foi dito acima, existem reuniões no início de cada um dos ciclos. O tempo atribuído a estes ciclos tem em conta uma pequena margem de erro para colmatar possíveis derrapagens que possam ocorrer na realização do projeto. 2.2 Ferramentas Utilizadas Na realização de um projeto de uma escala mais elevada, tal como acontece com o PJMAS, sendo um projeto de Dissertação/Estágio de Mestrado em Engenharia Informática, o planeamento do mesmo é uma etapa importantíssima para o seu sucesso. De seguida são descritas as ferramentas utilizadas para o planeamento do projeto. 2.2.1 Diagrama de Gantt Para calendarizar todas as tarefas envolvidas no projeto, possibilitando uma rápida e simples visualização das mesmas, foi construído um diagrama de Gantt. Desta forma, torna-se bastante 4 Luís Laranjeira - PJMAS fácil situar-se no projeto, verificar as metas e o tempo que se terá disponível para realização de cada uma, assim como as tarefas precedentes. Esta é uma ferramenta utilizada em grande escala a nível mundial, principalmente pela sua simplicidade e facilidade de perceção. 2.2.2 Work Breakdown Structure Esta ferramenta permite uma abordagem mais pormenorizada do projeto, já que o Diagrama de Gantt proporciona uma visão mais generalizada do mesmo. São assim divididas tarefas em mini tarefas proporcionando maior nível de controlo e detalhe do projeto ao autor. Foi determinado pelo autor em conjunto com a entidade acolhedora (Dognædis), que cada mini tarefa teria, no máximo, duas semanas de duração. Conjugando dessa forma o Work Breakdown Structure (WBS) com a metodologia adotada, em que cada ciclo de trabalho dura, sempre que possível, duas semanas. 2.3 Identificação de Riscos O projeto PJMAS continha alguns riscos quanto à sua completa implementação, pois não é uma aplicação standalone1 , mas sim um módulo para o motor de análise estático já existente na entidade acolhedora. Contudo, este módulo, apresenta-se bastante independente da aplicação existente, apenas interagindo com a mesma ao “entregar” a AST, podendo posteriormente, ser reaproveitado para novas ferramentas/aplicações. Outro risco identificado é a necessidade de identificar anotações em código Java (regularmente utilizadas em aplicações web, como por exemplo EJB, JPA, Java Message Service (JMS)...) e que podem resultar em vulnerabilidades, o risco neste caso é que o motor atualmente existente não possui tal funcionalidade, o que poderá inviabilizar a correspondência completa da AST que é entregue e ao tipo de nós que são esperados. Devido a este risco identificado, foi definido que, as anotações seriam tratadas apenas, após terminadas todas as outras funcionalidades da linguagem Java, de modo a não interferir com o resto do desenvolvimento e permitindo aos responsáveis pelo CodeV verificar se existe algum tipo de vulnerabilidades recorrente nesta prática e que dados necessitam de modo a construir a AST de acordo com tais parâmetros. Por fim, existe sempre o risco num tipo de projeto desta natureza, em que todas as funcionalidades acabam por estar diretamente dependentes umas das outras de, numa fase mais avançada do projeto aparecerem ambiguidades, em que pode ser necessária a alteração várias funcionalidades já desenvolvidas anteriormente, o que poderá causar atraso significativo no desenvolvimento do projeto. Como plano de contingência para qualquer desvio/atraso que pudesse ocorrer, tal como identificado anteriormente, foram definidas 4 tarefas com a prioridade Nice to Have(estão apresentadas no capítulo 4), que não seriam desenvolvidas caso se verificasse um atraso significativo no desenvolvimento dos requisitos Must Have. Já em relação ao hardware não deveria existir nenhum tipo de risco, visto que os requisitos relativos ao hardware se perspetivarem bastante acessíveis e existirem máquinas que já suportam o CodeV e que têm capacidade de suportar este novo módulo sem qualquer tipo de risco. 1 Aplicação auto-suficiente que não necessita de software de terceiros 5 Luís Laranjeira - PJMAS 2.4 Tarefas do Primeiro Semestre Na tabela 2.1 estão apresentadas as principais tarefas e metas planeadas para o primeiro semestre2 . Já o diagrama de Gantt completo, relativo ao mesmo período encontra-se no anexo A.1. Está igualmente anexado em B.1 o WBS referente ao mesmo período. Fase Ambientação à Empresa Planeamento das Atividades do Primeiro Semestre Diagrama de Gantt Relativo ao Primeiro Semestre WBS Relativo ao Primeiro Semestre Documentação Estado da Arte Estudo Geradores Parsers Existentes Comparação Geradores de Parsers Existentes Análise de Ferramentas Concorrentes ao CodeV Documentação Análise de Requisitos e Integração com o CodeV Requisitos Funcionais Requisitos Não Funcionais Estudo da Integração com o CodeV Análise de Riscos Documentação Definição da Aplicação Estudo da Árvore Arquitetura do Sistema Especificação do Parser Documentação Planeamento das Atividades do Segundo Semestre WBS Relativo ao Segundo Semestre Diagrama de Gantt Relativo ao Segundo Semestre Escrita Relatório Intermédio Início 18/09/2012 25/09/2012 25/09/2012 27/09/2012 02/10/2012 04/10/2012 04/10/2012 18/10/2012 26/10/2012 01/11/2012 06/11/2012 06/11/2012 09/11/2012 14/11/2012 21/11/2012 22/11/2012 27/11/2012 27/11/2012 06/12/2012 14/12/2012 25/12/2012 27/12/2012 27/12/2013 02/01/2013 04/01/2013 Fim 21/09/2012 03/10/2012 26/09/2012 28/09/2012 03/10/2012 02/11/2012 17/10/2012 25/10/2012 31/10/2012 02/11/2012 23/11/2012 08/11/2012 13/11/2012 20/11/2012 21/11/2012 23/11/2012 26/12/2012 05/12/2012 13/12/2012 21/12/2012 26/12/2012 03/01/2013 01/01/2013 03/01/2013 25/01/2013 Duração (d) 4 6 2 2 2 18 8 5 3 2 12 3 2 4 1 2 18 6 5 5 2 5 3 2 13 Tabela 2.1: Tabela Auxiliar do Diagrama de Gantt do Primeiro Semestre. Para o primeiro semestre a carga horária pré-definida, de acordo com os 12 European Credit Transfer and Accumulation System (ECTS) atribuídos pela Universidade de Coimbra (UC), equivale a 16 horas semanais. Cada dia definido na calendarização do primeiro semestre corresponde a 4 horas. 2 NOTA: Para a construção do diagrama de Gantt não foram considerados os feriados Nacionais em vigor no presente ano. No entanto, o autor responsabiliza-se por esses dias e compensa-os noutros dias úteis, mantendo assim as horas de esforço definidas no diagrama de Gantt 6 Luís Laranjeira - PJMAS 2.5 Tarefas do Segundo Semestre As tarefas para o segundo semestre foram significativamente alteradas em relação ao plano inicial. Esta modificação deveu-se a recomendações efetuadas pelo júri na defesa intermédia e de uma discussão entre o autor, o orientador Eng. Hugo Trovão e o Professor Doutor Luís Macedo. O plano inicial mantém-se apresentado no anexo A.2. Na tabela 2.2 estão apresentadas as principais tarefas e metas planeadas para o segundo semestre3 . Já o diagrama de Gantt completo relativo ao mesmo período encontra-se no anexo A.3. Está igualmente anexado em B.2 o WBS referente ao mesmo período. Fase Discussão sobre Defesa Intermédia Análise de Conselhos/Criticas proferidos pelo Júri na Defesa Intermédia Alteração dos aspetos considerados importantes para o desenrolar do estágio Adições ao Estado da Arte Análise e Testes aos Parsers Existentes Comparação dos Parsers Documentação Comparação Entre Criar ou Aproveitar um Parser Existente Especificação Completa da Gramática do Parser Instalação, configuração e ambientação às ferramentas necessárias Deteção da Linguagem Java Integração com o CodeV - 1ª Fase Deteção de Java nos JSP e Tags no Formato XML Alteração de Ciclos for na AST Extensão de Anotações Alteração nós da AST nas JSP Extensão múltiplas exceptions nos catch Testes Iterativos Testes Finais ao Parser Verificação 1: “Parsing”, AST e Nós Resultantes Verificação 2: Respeita requisitos não-funcionais Integração no CodeV - 2ª Fase Escrita Relatório Final Início 11/02/2013 11/02/2013 Fim 12/02/2013 11/02/2013 Duração (d) 2 1 12/02/2013 12/02/2013 1 13/02/2013 13/02/2013 18/02/2013 19/03/2013 21/02/2013 20/02/2013 15/02/2013 18/03/2013 20/02/2013 27/02/2013 6 3 1 2 5 28/02/2013 07/03/2013 06/03/2013 08/03/2013 5 2 11/03/2013 12/04/2013 17/04/2013 07/05/2013 13/05/2013 17/05/2013 23/05/2013 11/03/2013 27/05/2013 27/05/2013 30/05/2013 03/06/2013 07/06/2013 11/04/2013 16/04/2013 06/05/2013 10/05/2013 16/05/2013 22/05/2013 24/05/2013 20/05/2013 31/05/2013 29/05/2013 31/05/2013 05/06/2013 28/06/2013 24 3 14 4 4 4 2 55 5 3 2 3 16 Tabela 2.2: Tabela Auxiliar do Diagrama de Gantt do Segundo Semestre. Para o segundo semestre, visto no plano curricular atribuir 30 ECTS à dissertação/estágio, assume-se como a carga de esforço necessário 8 horas diárias, perfazendo 40 horas semanais, incluídas no planeamento e calendarização do diagrama de Gantt e WBS. Os testes iterativos foram realizados durante todo o desenvolvimento, ou seja, durante os 3 NOTA: Para a construção do diagrama de Gantt não foram considerados os feriados Nacionais em vigor no presente ano. No entanto, o autor responsabiliza-se por esses dias e compensa-os noutros dias úteis, mantendo assim as horas de esforço definidas no diagrama de Gantt 7 Luís Laranjeira - PJMAS 55 dias destinados ao efeito, embora o seu esforço será, apenas, 25% dos 55 dias. Isto significa que para cada funcionalidade definida, 1/4 do tempo é reservado para testes e para a correta validação de cada funcionalidade. O processo de estimação de cada tarefa baseia-se no método Three-point Estimate[4], em que para cada tarefa se estima o caso mais provável (se tudo correr como planeado), o melhor caso (se tudo correr melhor do que o esperado), e o pior caso (se tudo correr de forma errónea). No final da estimativa das variáveis anteriores, calcula-se o valor expectado para a tarefa cor(M C + (4 ∗ CP ) + P C) , em que MC corresponde a rente, em que este se baseia na fórmula 6 Melhor Caso, CP a Caso Provável e PC Pior Caso. Esta fórmula tem por base os slides disponibilizados pelo Professor Doutor Marco Vieira, referenciados em [4]. De referir que estimativa geral do projeto tem um valor esperado com probabilidade de 50%, com base num intervalo entre 2% a 98% de confiança. Para o desenvolvimento do planeamento foi seguida uma metodologia Bottom-up Estimation[4], que consiste em criar o WBS, estimar cada tarefa e obter o esforço geral do projeto PJMAS. O autor baseou-se nos seis passos fundamentais da metodologia Bottom-up, que são estes o de selecionar o estimador/equipa de estimação, obter os artefactos relevantes para a estimativa, criar o WBS, estimar cada tarefa, calcular o esforço geral do projeto e redefinir as estimativas se houver necessidade. A seleção do estimador recaiu sobre o autor do projeto e de um colaborador da entidade acolhedora com experiência na área da dissertação/estágio. Por outro lado a seleção dos artefactos relevantes, traduzem-se na arquitetura definida, nas tecnologias adotadas, na lista de requisitos, nas metas de entrega e nos testes a desenvolver. Para uma maior qualidade no processo de estimação de tarefas relativo ao segundo semestre foram incluídos quatro requisitos “Nice to Have” no planeamento do projeto, que correspondem sensivelmente a cento e catorze horas de esforço e/ou 14% do esforço do projeto. Esta opção foi tomada não só para enriquecer o projeto caso tudo decorresse conforme planeado, mas também para criar um espaço de manobra ao autor caso alguma tarefa MUST não corresse conforme planeado e demorasse mais tempo no seu desenvolvimento que o previsto inicialmente. Tarefa Total Melhor Caso* 88,53 *2% Confiança Caso Normal 100 Pior Caso** 116,13 **98% Confiança Caso Expectado 102,33 Tabela 2.3: Tabela da estimação geral do PJMAS, 2º semestre. Na tabela 2.3 estão apresentados os valores previstos para a duração do projeto no segundo semestre para o melhor caso, caso normal, pior caso e caso expectado. No anexo C o leitor pode visualisar as tabelas quer de tarefas individuais, quer de todo o segundo semestre, que deram origem à tabela global de estimação do PJMAS. 8 Capítulo 3 Estado da Arte Neste capítulo são apresentadas as pesquisas efetuadas na primeira parte do estágio, análise e comparação de parsers para a linguagem Java existentes. Foi estudado se traria mais vantagens a construção de um novo parser ou o aproveitamento de um existente. Foram analisadas ferramentas para construção do parser, passando pela comparação das mesmas, resultando na escolha da ferramenta para o projeto. Foi efetuada ainda uma breve análise a algumas ferramentas similares ao funcionamento do CodeV, analisando igualmente vulnerabilidades de código Java. 3.1 Parsers Java Sendo o propósito do atual projeto a criação de um parser na linguagem de programação Java, capaz de gerar uma AST igualmente na linguagem Java, foram analisados alguns parsers existentes com as mesmas propriedades, mais precisamente, o Eclipse Java Development Tools (JDT) Core, o JRefactory, o JavaParser e o PMD, sendo analisadas neste capítulo as suas caraterísticas e suas funcionalidades. Após esta etapa foi efetuada uma comparação entre os parsers apresentados no capítulo atual, tendo sido efetuados vários testes, igualmente explicados neste capítulo, de modo a permitir ao leitor uma compreensão das análises efetuadas e conclusões do autor. 3.1.1 Eclipse JDT Core Component Eclipse JDT[5] é um projeto desenvolvido e mantido pelo Eclipse. Tem como objetivo fornecer todas as ferramentas necessárias para um Integrated Development Environment (IDE) que suporte o desenvolvimento de qualquer aplicação na linguagem Java. O JDT Core Component é a infraestrutura Java do IDE Java, que inclui as seguintes funcionalidades[6]: • Um compilador Java incremental, que permite correr e efetuar debug de código, mesmo este ainda tendo erros por corrigir; • Um Modelo Java que fornece uma Application Programming Interface (API) para navegar na árvore de elementos Java. A árvore de elementos define a visão central de um projeto Java. Percorre elementos como “package”, “compilation units”, classes binárias, tipos, métodos e campos; 9 Luís Laranjeira - PJMAS • Um Modelo de Documento Java que fornece uma API para manipulação de um documento de código fonte Java; • Assistente de código e suporte de seleção de código; • Uma infraestrutura de procura baseada em indexação, que é utilizada para pesquisas, assistência de código, computação de tipo de hierarquia e “refactoring”; • Suporte de avaliação quer numa página “scrapbook”, quer num contexto de debug; • Formatação de código fonte Java. A infraestrutura do JDT Core Component não tem dependências embutidas em alguma versão especifica de Java Development Kit (JDK) nem depende, igualmente, de qualquer “user interface” Java em particular, podendo ser executado sem quaisquer dependências. Através desta ferramenta é possível efetuar o parsing de ficheiros de código fonte Java, criando uma AST, que é reaproveitada para fins diferentes, representados nas várias funcionalidades acima apresentadas. O Eclipse JDT Core Component está sob uma licença Eclipse Public License (EPL) v1. 3.1.2 JRefactory Inicialmente desenvolvido por Chris Seguin, JRefactory[7] é um software com possibilidade de integração em vários IDEs, mais precisamente jEdit, Netbeans, JBuilder X e Ant. No entanto, pode ser executado como uma aplicação “aplicação standalone”. Algumas das funcionalidades apresentadas pela aplicação são: • Pretty Printer/Beautifier, é uma ferramenta que permite uma limpeza da indentação e da formatação do código fonte; • JRefactory, permite efetuar “refactoring” ao código fonte, com várias opções explicadas mais pormenorizadamente na página do JRefactory[7]; • AST Viewer, mostra o resultado do parser Java no formato de AST; • Metrics, reúne métricas sobre o código fonte Java; • BugFinding, utiliza a ferramenta findbugs de modo a conseguir encontrar falhas mais comuns em código fonte Java. É um software gratuito estando sob uma licença Apache License, v2[8]. 3.1.3 JavaParser O JavaParser[9] é um parser criado e desenvolvido por Júlio Vilmar Gesser. Este parser suporta a versão Java 1.5, efetuando o “parsing” e criando a AST do código fonte Java analisado. As suas principais caraterísticas são: • Baixo consumo de memória; • Boa performance; • Fácil utilização; 10 Luís Laranjeira - PJMAS • A AST pode ser modificada; • A AST pode ser criada a partir do inicio. JavaParser foi criado através do gerador de parsers JavaCC, estando o ficheiro da gramática, bem como todo código fonte necessário, disponível para download e utilização, sob uma licença GNU Lesser GPL[10] 3.1.4 PMD O PMD[11] é um analisador de código fonte que procura falhas de programação comuns, como variáveis não utilizadas, estados “catch” vazios, criação de objetos desnecessários, entre outras. De momento suporta as linguagens de programação Java, JavaScript, eXtensible Markup Language (XML), eXtensible Stylesheet Language (XSL). Para além das caraterísticas apresentadas o PMD possui ainda a ferramenta “copy-pastedetector”(CPD), que deteta código fonte duplicado em Java, C, C++, C#, PHP, Ruby, Fortran, JavaScript. A ferramenta possui plugin para diversos IDEs, fornecendo ainda todo o código fonte da aplicação, bem como a gramática dos parsers utilizados na criação da AST. Embora suporte JSP, apenas constrói a AST sem o código Java, ou seja, tudo que seja código Java dentro do JSP não é “parsado’[12]’. As gramáticas dos parsers foram criadas usando o gerador de parser Java Compiler Compiler (JavaCC), estando as mesmas disponíveis junto com o código fonte da aplicação. A aplicação está sob uma licença BSD[13]. 3.2 Comparação Parsers Neste capítulo serão apresentados, numa primeira fase, os testes efetuados aos parsers referidos no capítulo anterior, numa segunda fase os resultados obtidos dos testes efetuados e, por fim, uma comparação entre os parsers e as funcionalidades que o parser implementado tem. Todas as especificações referentes à máquina e ao ambiente de testes estão presentes no capítulo 7.3. 3.2.1 Testes Neste capítulo serão apresentados os testes efetuados aos parsers analisados, estando descritos pormenorizadamente de forma a facilitar a compreensão do leitor e possibilitando a sua replicação caso o leitor assim o pretenda. 3.2.1.1 Configuração e Teste ao Java 1.6 Antes de qualquer teste ser efetuado é necessário configurar o software que se pretende testar. Inicialmente o autor configurou cada um dos parsers, sendo testado o funcionamento destes com um ficheiro de código fonte Java bastante simples. O ficheiro foi criado com o JDK 1.6. Esta opção deve-se ao facto de alguns parsers terem sido criados para a versão 1.5 do JDK, como em termos de sintaxe não existiram alterações entre as duas versões referidas, cada parser tinha que efetuar o parsing corretamente do ficheiro de teste. 11 Luís Laranjeira - PJMAS O conteúdo do referido ficheiro é composto por inicialização de algumas variáveis e/ou objetos, uso de um ciclo “for” com várias condições “if-else” e chamadas a algumas funções. 3.2.1.2 Teste ao Java 1.7 Com o lançamento do JDK 1.7, foram efetuadas algumas mudanças no sintaxe do Java[14], ou seja, foram adicionadas novas funcionalidades que implicam alterações na gramática dos parsers Java existentes. Neste teste foi criado um ficheiro de código fonte reduzido, com algumas das novas funcionalidades presentes no JDK 1.7, a junção de várias possíveis exceções num único “catch”[15], um “switch-case” com Strings e instanciações de Objetos no Try. Desta forma foi possível verificar se algum dos parsers analisados suportava as novas funcionalidades do JDK 1.7. 3.2.1.3 Teste a JSP Neste teste, tal como o título o indica, foi testado o suporte de JSP por parte dos parsers. Para efetuar o teste, o autor utilizou um ficheiro com várias partes de código Java. O ficheiro JSP analisado pertence a uma aplicação desenvolvida pelo autor numa cadeira anteriormente frequentada, estando o código bem formatado e funcional. O ficheiro JSP contém, para além de HyperText Markup Language (HTML), código fonte Java “comum”, import de vários objetos e inicialização de EJB. 3.2.1.4 Teste a Anotações, EJB e WS Tal como no teste anterior, pretende-se analisar tecnologias utilizadas no JavaEE/J2EE. Neste teste o foco incidirá nas anotações que são uma parte essencial nas tecnologia EJB e Web Service (WS), utilizando diferentes tipos e declarações de anotações. Para estes testes, foram analisados três ficheiros distintos: primeiro um ficheiro de código fonte que representa um EJB Stateless, o segundo representa um WS, enquanto que para o terceiro e último ficheiro deste teste foi efetuada uma pesquisa e sobre os vários tipos de declarações de anotações existentes no Java, tendo o autor criado um ficheiro de código fonte utilizando os tipos identificados. De referir que para o primeiro e para o segundo teste, foram utilizados ficheiros de código fonte desenvolvidos pelo autor em aplicações de cadeiras do Mestrado em Engenharia Informática da Universidade de Coimbra. 3.2.1.5 Teste ao Performance e à Memória Utilizada O último efetuado consistiu em determinar a performance e a memória gasta por cada parser. Para tal foi analisado um ficheiro de código fonte na linguagem Java, gerado a partir de uma gramática do JavaCC, contendo 11080 linhas de código. Para determinar a performance do parser, foi introduzido um contador no código fonte que invoca o parser. Antes de iniciar o parsing do ficheiro é guardada a data local em milissegundos, e ao terminar o parsing do ficheiro é guardada a data atual também em milissegundos, sendo o tempo total de execução calculado através da subtração do primeiro valor ao segundo. Já para determinar a memória utilizada pelo parser para análise do ficheiro, foi utilizado o VisualVM[16], uma ferramenta que permite visualizar detalhadamente várias caraterísticas relativas às aplicações Java em execução no Sistema Operativo. 12 Luís Laranjeira - PJMAS Cada parser efetuou este teste 30 vezes, sendo os valores finais, quer de memória utilizada, quer de tempo que demorou a efetuar o parsing, a média de todos os testes efetuados. Para efetuar os testes com maior independência do IDE utilizado no desenvolvimento, foi gerada uma aplicação Java executável (jar), para cada parser. 3.2.2 Resultados Obtidos Parser Eclipse JDT JavaParser JRefactory PMD PJMAS JDK 1.6 X X X X X JDK 1.7 X × × X X JSP × × × × X WS X X × X X EJB X X × X X Anotações X X × X X Tabela 3.1: Funcionalidades dos parsers analisados e do apresentado na dissertação. Na tabela 3.1 estão apresentados os resultados dos testes de verificação às funcionalidades suportadas por cada parser, embora as anotações façam parte do JDK 1.6 e JDK 1.7. Como são bastante importantes em tecnologias JavaEE/J2EE e bastante mais utilizadas nesse contexto, foram utilizados testes específicos para essa funcionalidade, separando-a dos JDKs. O Eclipse JDT Core Component, a par do PMD, foram os parsers que demonstraram maior suporte às vastas tecnologias. O Eclipse JDT Core Component em todos os casos de teste apresentou uma AST completa e, de acordo com os nós do parser, correta. O único teste que não efetuou o parsing com sucesso foi o parsing de ficheiros JSP, embora não tenha retornado qualquer erro, a AST não é preenchida, possuindo apenas o nó raiz (CompilationUnit). Já por sua vez, o PMD, no teste referente ao JSP, retornou erro de parsing, algo já esperado pois possui um parser de JSP, no entanto, este parser, tal como referido anteriormente, não analisa o código fonte Java. O JavaParser, em termos gerais também mostrou um bom suporte às diversas tecnologias, não suportando apenas o JDK 1.7 e, tal como o Eclipse JDT Core Component, não suporta JSP. Em ambos os casos é retornado um erro pelo parser, indicando que não esperava determinado token na posição em que aparece. Já o JRefactory demonstrou ser o parser com menos tecnologias suportadas. No entanto, e após vários testes efetuados, o autor concluiu que apenas as anotações mais simples1 não são suportadas. Devido a esse problema não teve sucesso nas restantes tecnologias. A vantagem do parser PJMAS, desenvolvido na presente dissertação, é que suporta todas as funcionalidades referidas anteriormente, tornando-se uma mais valia, visto os demais não conseguirem analisar a linguagem Java em JSP. Já os resultados aos testes de avaliação de performance e memória utilizada, estão apresentadas as médias obtidas para cada parser na tabela 3.2. No anexo D estão apresentados os resultados individuais para cada teste (como referido anteriormente foi executado 30 vezes cada teste). Através da análise dos resultados obtidos é possível visualizar que o Eclipse JDT Core Component demora bastante mais tempo a efetuar o parsing que os restantes parsers. Também em quantidade de memória utilizada supera, por grande diferença, os restantes parsers. isto pode dever-se à aplicação possuir bastantes funcionalidades em comparação com as demais. No 1 por exemplo: @Override 13 Luís Laranjeira - PJMAS Parser Eclipse JDT JavaParser JRefactory PMD Tempo médio (ms) 1236.23 343.77 602.10 701.23 Memória média (MB) 66.59 14.28 42.57 36.83 Tempo médio 1000 linhas (ms) 111.57 31.03 54.34 63.29 Memória média 1000 linhas (MB) 6.01 1.29 3.84 3.32 Tabela 3.2: Resultados aos testes de performance e memória utilizada. entanto, para o propósito do projeto do presente estágio/dissertação, pretendia-se que o parser possuísse maior performance e que mantivesse um baixo consumo de memória do sistema, de modo que o sistema conseguisse sempre executar as várias aplicações em funcionamento sem qualquer tipo de problemas. 3.3 Estudo da Sustentabilidade do Desenvolvimento do Parser Para a criação da AST, existiam duas soluções possíveis, criar um novo parser de raiz direcionado para o motor de análise de vulnerabilidades ou aproveitar um parser existente desenvolvido por terceiros e efetuar as operações necessárias para traduzir a AST. Sabendo que nenhum dos parsers analisados suporta JSP será, ainda, necessário alterar a gramática para suporte do mesmo. Para a apresentação das vantagens de cada uma das soluções, e de forma a obter melhor comparação e perceção o autor decidiu criar uma tabela com as principais vantagens e desvantagens de cada solução. Para comparação com um dos parsers analisados anteriormente, foi selecionado o PMD, pois foi o parser que, a par do Eclipse JDT Core Component, demonstrou suportar mais tecnologias. No entanto a nível de performance é mais rápido na análise do código e necessita de menos memória. Novo Parser Aproveitamento Parser Existente • Integração Java com JSP simplificada devido ao conhecimento do parser. • Linguagem Java até à versão 1.7 completamente suportada • Possibilidade de obter melhores valores de performance e/ou memória utilizada. • Bom suporte, correção de erros, atualizações futuras para novas versões são “garantidas”. • Parser criado direcionado para a solução existente (CodeV), visando assim especialmente os nós (aspetos) considerados mais importantes. • Sem necessidade de desenvolvimento do parser na parte Java. • Testes ao parser quase desnecessários, visto ser uma ferramenta bastante utilizada, com uma larga comunidade. • Integração com o CodeV facilitada, visto ser construido o parser direcionado para o mesmo. Tabela 3.3: Tabela representativa das vantagens de cada uma das opções possíveis. 14 Luís Laranjeira - PJMAS Novo Parser Aproveitamento Parser Existente • Parser criado de raiz, sendo necessário mais tempo para desenvolvimento. • Necessidade de construção de um tradutor da AST devolvida para a desejada e/ou alterações na gramática. • Necessidade de mais testes, de forma a garantir parsing de ficheiros diversificados. • Sem suporte para JSP. Integração envolve compreensão da gramática do parser com bastante detalhe, seria gasto algum tempo para compreensão da mesma. • Todo o tipo de futuras atualizações ficam a cargo da entidade acolhedora, quer para correções, quer para atualizações possíveis na própria gramática do JDK. • Caso se aplicasse um tradutor, a performance certamente diminuiria e a memória necessária aumentaria. • Integração com o CodeV mais demorada com um parser criado especificamente para o efeito. Tabela 3.4: Tabela representativa das desvantagens de cada uma das opções possíveis. Como é possível observar através das tabelas 3.3 e 3.4, ambas opções acarretam pontos positivos e negativos na implementação do parser. Foi efetuada uma reunião entre o autor e responsáveis pela entidade acolhedora com o intuito de escolher a solução que melhor se enquadraria. Como resultado foi escolhido manter o plano inicial e criar um parser de raiz direcionado para CodeV. Para tal decisão teve grande importância o facto de nenhum dos parsers analisados suportarem JSP que é um elemento de extrema importância para o produto da entidade acolhedora. O facto de um parser criado de raiz se focar nos pontos essenciais e produzir uma AST especificamente direcionada para o CodeV foi outra caraterística preponderante para a decisão final. 3.4 Geradores de Parsers Existentes Foram identificados vários geradores de parsers e AST, recaindo a análise para quatro ferramentas mais populares e com uma comunidade maior, possibilitando assim, futuramente, maior facilidade de pesquisa e ajuda em possíveis problemas no desenvolvimento e manutenção do parser e/ou AST. 3.4.1 YACC / Bison O Yet Another Compiler Compiler (YACC)/Bison é uma das ferramentas com mais anos de utilização por os mais diversos utilizadores, tanto para criar parsers como para criar compiladores de novas linguagens de programação. A análise lexical é definida num ficheiro “.l”, fazendo uso da ferramenta lex. Na análise lexical são especificadas as expressões regulares aceites pelo programa, os tokens a ser devolvidos, assim como a passagem dos valores lidos para o ficheiro YACC (.y)[17]. Já no ficheiro YACC são definidas todas as regras de análise gramatical que o parser deve seguir, de modo a cumprir os requisitos pré estabelecidos, podendo ser definidas regras na lin15 Luís Laranjeira - PJMAS guagem C. É, ainda, necessário criar os nós que vão construir a árvore igualmente na linguagem C, sendo por fim gerada a árvore compilando com o Bison[18]. A notação da gramática aceite é Backus–Naur Form (BNF) como algoritmo de análise lexical, utilizando um Deterministic Finite Automaton (DFA), já para algoritmo de parser utiliza Left-to-right Right-derivation parsing (LR) ou Look-Ahead Left-to-right Right derivation parsing (LALR). Atualmente já é possível gerar o parser para a linguagem C, C++ e Java2 , embora venham as ferramentas necessárias para o funcionamento em Linux e Unix, também é possível a instalação e configuração, salvo erro, em todas as plataformas. Os parsers gerados desta forma são da tipologia bottom-up. Esta é uma solução com licença General Public License (GNU GPL)[19]. 3.4.2 JavaCC Esta é uma ferramenta mais recente, tendo sido lançada com o nome Jack em 1996 pela Sun Microsystems. Mais tarde, os autores responsáveis pelo projeto criaram a sua própria companhia tendo alterado o nome para JavaCC[20]. A análise sintática, lexical e regras da gramática são escritas no mesmo ficheiro, com o intuito de tornar a leitura da gramática mais simples ao programador. Os parsers gerados pelo JavaCC , ao contrário do YACC, são top-down, o que evita a recursividade à esquerda. Permite a especificação de Extended Backus–Naur Form (EBNF)[21] que libertam da necessidade do uso de recursividade à esquerda e tornam a leitura muito mais simples. Por fim, utiliza o algoritmo de parsing Left Linear parsing (LL)(k) com um valor de lookahead3 por default 1, mas variável para o programador, consoante as necessidades em partes diferentes do parser, podendo resolver, dessa forma, ambiguidades “shift-shift”, sendo que os conflitos shift-reduce e reduce-reduce não são um problema nos parsers top-down. A ferramenta é multiplataforma e funciona sob o Java Virtual Machine (JVM), possui plugin de integração com o Eclipse e permite criar parsers na linguagem Java e C++. A criação da AST é bastante simples, pois tem incorporado o JJTree unicamente para o efeito. Está sob uma licença Berkeley Software Distribution (BSD)[13]. 3.4.3 ANTLR Com início de desenvolvimento em 1989, por Terence Parr na Universidade de São Francisco, foi lançado a sua primeira versão estável em Fevereiro de 1992. Atualmente, continua a ser desenvolvido, sendo a última versão estável a 3.4[22]. Neste momento permite gerar parsers e árvores de sintaxe abstratas. Em vários pontos o ANother Tool for Language Recognition (ANTLR) é bastante parecido com o funcionamento do JavaCC, sendo a análise sintática, lexical e regras da gramática definidas igualmente no mesmo ficheiro. A linguagem é especificada usando gramáticas livres de contexto que são expressas usando EBNF. O algoritmo de parser usado é o LL(*), que é top-down, descendente recursivo. A diferença deste algoritmo em relação ao LL(k), é que não se restringe a um K valor, parte do pressuposto que existirá um valor k de lookahead que permitirá encontrar o token diferente de modo a tomar a sua decisão de parsing. É uma ferramenta multiplataforma visto correr, tal como o JavaCC, numa JVM, existindo plugin para Eclipse e configuração para Netbeans, tendo enorme diversidade de linguagens alvo (finais), num total de 12(Ada, ActionScript, C, C++, C#, Emacs ELisp, Objective C, Java, JavaScript, Python, Ruby e PHP). Este software está sob uma licença BSD[13]. 2 Embora 3 Valor numa fase experimental. correspondente à letra k 16 Luís Laranjeira - PJMAS 3.4.4 Gold Gold[23], é uma ferramenta criada em 2001 por Devin Cook, desenvolvida desde então com ajuda de vários colaboradores, sendo a última versão estável disponível aquando da escrita deste documento, a 5.2. Continua a ser desenvolvido, contendo inclusive tópicos de discussão acerca dos “bugs” descobertos até ao momento na nova versão e que estão a ser corrigidos. Aceita gramáticas na notação BNF e utiliza LALR como algoritmo de parsing. A gramática e o código, ao contrários das ferramentas acima descritas, não são escritas em conjunto, mas sim separadamente. Atualmente, o GOLD funciona para as linguagens ANSI C, Assembly - Intel x86, C, C++, C#, Delphi 5 & 6, DigitalMars D, Java, Pascal, Python, Visual Basic 6, Visual Basic .NET, todas as outras linguagens .NET, todas as outras linguagens ActiveX, das ferramentas analisadas é a que possui maior número de linguagens alvo. Em termos de plataformas, é uma ferramenta disponível apenas para Microsoft Windows, estando, no entanto, disponível suporte para outras plataformas através de plugins para algumas das linguagens suportadas. É uma ferramenta gratuita estando sob uma licença Zlib[24]. 3.5 Comparação e Seleção de Geradores de Parsers Na tabela 3.5 estão representadas várias caraterísticas consideradas relevantes para a construção do parser e respetiva AST proposto neste estágio curricular. É ainda efetuada uma análise detalhada sobre entre as mesmas. Caraterística Licença Algoritmo Parsing Notação Gramática Gramática/Código Analisador Léxico Plataforma Desenvolvimento IDE Suporta Java Simplicidade Geração AST (1-5) Yacc/Bison Gratuita LALR(1) BNF misto independente todas não sim - JavaCC Gratuita LL(k) EBNF misto gerado JVM sim sim 5 ANTLR Gratuita LL(*) EBNF misto gerado JVM sim sim 4 GOLD Gratuita LALR(1) BNF independente gerado Microsoft Windows sim sim - Tabela 3.5: Tabela de comparação de geradores de parsers Como é possível verificar na tabela 3.5, todas as ferramentas analisadas são gratuitas, condição essencial para a realização do projeto, existindo neste campo um leque de geradores de parsers gratuitos bastante bom. Quanto ao algoritmo de parsing utilizado, existem várias diferenças, o YACC e o GOLD utilizam LALR(1), considerado um algoritmo bastante eficiente em encontrar o caminho bottomup correto numa simples análise ao “input”, pois não necessita de recorrer ao backtracking. No entanto, também se torna mais fácil aparecerem ambiguidades na gramática do parser. Já no que diz respeito à notação da gramática, a EBNF tem a vantagem de não necessitar de usar a recursividade à esquerda em alguns casos, bem como, permitir o uso de expressões regulares que acabam por proporcionar uma leitura mais percetível da gramática (por exemplo A ::= y(x)* versus A ::= Ax|y). A necessidade de suporte para Java, tal como referido anteriormente em 1.4, prende-se com o facto dos nós da AST atuais, serem classes Java, tendo assim um maior reaproveitamento 17 Luís Laranjeira - PJMAS de código existente, para além da certeza na compatibilidade com a plataforma de análise de vulnerabilidades. Para a próxima análise foram descartados os geradores YACC e GOLD. O primeiro por ser uma ferramenta com a qual é mais complicado trabalhar que qualquer outra analisada, e o segundo, porque a plataforma de desenvolvimento suportada atualmente é apenas Microsoft Windows e o sistema operativo usado para desenvolvimento é Linux. Embora existam soluções para contornar o problema, o autor considerou desnecessário tal situação quando existem outras ferramentas tão ou mais capazes para o mesmo fim a funcionar perfeitamente no sistema operativo utilizado. Foram ainda analisados todos os passos necessários para geração da AST para as restantes ferramentas. Foram utilizados para este teste exemplos simples, de modo a perceber melhor o funcionamento e a proporcionar uma análise completa. Em ambas as ferramentas foi simples gerar a AST correspondente ao exemplo testado, no entanto, o autor considerou o JavaCC mais direto, o que justifica a diferença mínima nas notas atribuídas. Para além de todos os fatores apresentados, o JavaCC já foi utilizado anteriormente na entidade acolhedora para desenvolvimento do parser de PHP. Em termos futuros é mais vantajoso para a entidade acolhedora os parsers existentes serem gerados com a mesma ferramenta, uma vez que a sintaxe e as funcionalidades alteram sempre. Futuramente, caso seja necessário, é mais simples um programador integrar-se apenas com um gerador de parsers do que com vários. Face aos testes realizados e aos resultados obtidos, o autor decidiu utilizar para o presente estágio, como ferramenta para gerar o parser o JavaCC. 3.6 Aplicações Concorrentes ao CodeV Sendo o parser um módulo do produto final que é o CodeV, foram examinadas algumas aplicações concorrentes que analisam igualmente código fonte afim de verificar as vulnerabilidades existentes, permitindo ao cliente (utilizador) corrigi-las de modo a melhorar os níveis de segurança da sua aplicação. As análises às aplicações concorrentes ao CodeV estão presentes no anexo 3.6. 18 Capítulo 4 Análise de Requisitos Neste capítulo são apresentados os requisitos funcionais e não funcionais da aplicação e, por fim, a priorização das funcionalidades implementadas durante a presente dissertação. Deste modo são abordados não só aqueles que se denotam como requisitos técnicos da ferramenta, mas também a especificação das condições necessárias para que a mesma funcione corretamente mas sem afetar o sistema e os restantes módulos da aplicação. 4.1 Requisitos Funcionais Um requisito funcional descreve uma determinada ação que a aplicação deverá providenciar. 4.1.1 Parsing da Linguagem Comum Java O parser desenvolvido deve suportar toda a linguagem comun Java, incluindo a versão mais recente da sintaxe JDK 1.7. O presente requisito foi dividido em 9 funcionalidades distintas: • Comentários; – Detetar e descartar, pois não constituem valor para a análise de vulnerabilidades. • Packages e Imports; – Detetar ambos os tipos de declarações; • Classes, Enum e Interface; – Detetar todas as declarações dos diferentes tipos. • Variáveis/Objetos; – Detetar variáveis/objetos e Constantes existentes no código fonte; – Detetar operações que envolvam os variáveis e/ou constantes (adição, subtração, comparação, etc); • Funções; – Detetar métodos e Construtores existentes no código fonte. 19 Luís Laranjeira - PJMAS • Condições; – Detetar condições if-else; – Detetar switch-case; – Detetar declarações “default:” e “assert:”. • Iterações; – Detetar ciclos for; – Detetar ciclos while; – Detetar ciclos do-while. • Try Catch; – Detetar expressões try-catch-finnaly. • Anotações e @Interface. – Detetar anotações presentes ao longo do código fonte; – Detetar declarações @Interface, que permitem definir anotações personalizadas. O parser deve identificar corretamente cada uma delas, criando assim o nó da AST correspondente com os atributos distintos que cada uma possui. 4.1.2 Parsing Código Fonte Java e declarações XML nas JSP Nas JSP e no formato de XML podem ser declaradas várias propriedades, instanciados/modificadas/exibidas Beans, instanciadas/modificadas/exibidas variáveis e/ou objetos, indicação de página a rederecionar em caso de erro da atual (tipo de Try-Catch em JSP), imports para o JSP, entre outras caraterísticas importantes. É, portanto, deveras importante efetuar parsing a todas essas tags. O parser desenvolvido deve identificar as tags e declarações no formato XML existentes nos JSP, de modo a permitir ao motor de análise de vulnerabilidades analisar as mesmas e identificar possíveis vulnerabilidades. As tags possíveis de detetar podem, assim, ser divididas em 7 grupos distintos: • Comentários; – Deteção de comentários nas JSP e descartarem os mesmos por não terem valor para a análise de vulnerabilidades. • Código HTML; – Deteção de HTML nas JSP. • Scriptlet JSP e XML (“<%” e “<jsp:scriptlet”); – Deteção de declarações Scriptlet nos dois formatos, que permitem iniciação de código Java. • Declaration JSP e XML (“<%!” e “<jsp:declaration”); – Deteção de declarações Declaration em ambas as formas, que permitem declarações de novas funções/métodos em Java. 20 Luís Laranjeira - PJMAS • Expression JSP e XML (“<%=” e “<jsp:expression”); – Deteção de declarações expression. • Directive JSP e XML “<%@” e “<jsp:directive.”; – Deteção de declarações directive e de todas as propriedades possíveis de definir, como por exemplo Beans, Imports, páginas de erros, entre outros. • Standard Actions (“<jsp:”) – Deteção de declarações standard, permitem, entre outras opções, atribuir valores a propriedades dos Beans, apresentar valores na aplicação e incluir outras páginas. Sempre que existam tokens que identifiquem alterações entre código JSP e Java, o parser deve suportar o mesmo, integrando com as funcionalidades da linguagem Java acima descritas. 4.1.3 Alteração aos Ciclos for na AST Os ciclos for acarretam complexidade extra para o motor de análise de vulnerabilidades pois têm várias declarações e opções possíveis. Com esta alteração pretendeu-se transformar os ciclos for em ciclos while e reduzir, desta forma, a complexidade de análise de vulnerabilidades. A razão para a diminuição da complexidade prende-se com o facto do motor de vulnerabilidades suportar várias linguagens e de cada uma ter declarações diferentes, aumentando a complexidade do mesmo, pois geram nós diferentes. Como os ciclos while são iguais em PHP e em Java, com a alteração é possível reaproveitar vários processos já existentes no CodeV. 4.1.4 Extensão de Anotações Com esta funcionalidade pretendeu-se, após a geração da AST completa, localizar as anotações presentes na mesma e comparar com as funções existentes noutros ficheiros de código fonte. Caso sejam detetadas com sucesso a função que é invocada ao utilizar a anotação, são substituídos os nós referentes à mesma, pelos nós da função correspondente. Esta funcionalidade permite ao motor de análise de vulnerabilidades uma análise mais direta do código. 4.1.5 Extensão Múltiplos Exceptions nos Catch do JDK 1.7 Após o lançamento da última versão do JDK 1.7 passou a ser possível a declaração de Catch que englobem múltiplos tipos de exceções. Esta situação acarreta problemas para o CodeV, pois na lógica implementada para análise de vulnerabilidades, cada variável tem apenas um tipo de objeto associado. O propósito desta modificação na AST é aumentar a compatibilidade e, por consequência, diminuir as alterações necessárias a efetuar no motor de análise de vulnerabilidades. 4.1.6 Alterações à AST nas JSP As JSP contém várias declarações no formato XML que permitem manipulação de objetos Java (declaração de Beans, apresentação de valores de variáveis, entre outras). O CodeV não possui, para já, suporte para as declarações dos JSP no formato XML e terá que ser criada toda a lógica de análise de vulnerabilidades para os novos tipos de nós. 21 Luís Laranjeira - PJMAS O propósito da presente funcionalidade é efetuar alteração nos nós da AST de algumas das declarações em que exista possibilidade de replicar o conteúdo em formato XML com código fonte Java que efetue as mesmas funcionalidades. O autor efetuou um estudo sobre as declarações existentes dos JSP em XML e sua função nas aplicações e apresentou ao orientador Hugo Trovão, de modo a identificar as declarações mais importantes na análise de vulnerabilidades. Após a reunião efetuada foi definido que seria interessante efetuar a alteração dos nós da AST correspondentes às seguintes declarações: • <jsp:getProperty> • <jsp:setProperty> • <jsp:useBean> • <jsp:include> • <jsp:forward> 4.2 Requisitos Não Funcionais Um requisito não funcional é uma exigência que especifica critérios que podem ser usados para julgar o funcionamento de um sistema, ao invés de comportamentos específicos (ao contrário dos requisitos funcionais que definem o comportamento especifico de uma funcionalidade), podendo estes constituir uma restrição para os requisitos funcionais. 4.2.1 AST Gerada Compatível com a Plataforma Existente Existindo uma aplicação completamente funcional, uma das exigências que se prende com a criação de um novo módulo é a compatibilidade do mesmo com a aplicação existente. Na presente dissertação a AST gerada pelo parser tinha que corresponder à estrutura esperada pelo motor de análise de vulnerabilidades, sendo a árvore composta por nós adequados e nas sequências adequadas, ou então o motor não funcionará corretamente. 4.2.2 Tempo de Execução O parser deveria ter algum nível de performance, tendo o autor definido que o parser deveria demorar menos tempo que a média dos parsers analisados anteriormente. Significa que para o ficheiro de teste utilizado para análise da performance e memória utilizada na comparação dos parsers analisados no capítulo 3.2, o parser desenvolvido deveria demorar menos que 720 milissegundos a efetuar o parsing do ficheiro de teste em causa. Estes valores são válidos para a máquina de testes utilizada e apresentada detalhadamente no capítulo 7.3. 4.2.3 Tamanho de Memória Usada Quanto à memória máxima utilizada, o autor baseou-se igualmente no princípio do requisito anterior, ou seja, o parser deveria utilizar menos memória que a média observada para os parsers analisados, ou seja, um valor inferior a 40 MB para o ficheiro de testes. Mais uma vez, estes valores são válidos para a máquina de testes utilizada, apresentada detalhadamente no capítulo 7.3. 22 Luís Laranjeira - PJMAS 4.2.4 Datas Definidas para Entregas Como último requisito não funcional, mas não menos importante, estão as datas definidas para entrega dos relatórios (defesa intermédia e final), sendo estas as datas limite para termito das tarefas pré-definidas no início do ano letivo. 4.3 Classificação dos Requisitos Requisito Linguagem Java Comentários Packages e Imports Classes/Enum/Interface Variáveis/Objetos Funções Condições Iterações Try Catch Anotações e @Interface JSP Comentários Deteção HTML Scriptlet JSP e XML Declaration JSP e XML Expression JSP e XML Directive JSP e XML Standat Actions Alteração de Ciclos for Extensão de Anotações Extensão de Múltiplos Catch Alteração nós da AST nas JSP Classificação MUST MUST MUST MUST MUST MUST MUST MUST MUST HAVE HAVE HAVE HAVE HAVE HAVE HAVE HAVE HAVE MUST HAVE MUST HAVE MUST HAVE MUST HAVE MUST HAVE MUST HAVE MUST HAVE NICE TO HAVE NICE TO HAVE NICE TO HAVE NICE TO HAVE Tabela 4.1: Tabela classificação dos requisitos Na tabela 4.1 estão todos os requisitos funcionais a implementar durante a presente dissertação, tendo sido classificados como “Must Have” e “Nice to Have”. A primeira classificação foi atribuída a todos os requisitos que tinham obrigatoriamente que ser implementados durante a dissertação, enquanto que os segundos, foram equacionados e seria interessante, também, serem implementados. No entanto, devido à data de entrega final do projeto, seriam apenas implementados caso existisse tempo suficiente para tal. Para a classificação dos requisitos foi tida em linha de conta a importância dos mesmos para o produto final. Os requisitos “Must” foram considerados necessários para a conclusão do parser e para o bom funcionamento do motor de análise de vulnerabilidades e para o parser estar completo é necessária a implementação de todos eles. No que diz respeito aos requisitos “Nice to Have”, foram requisitos que, caso não aparecessem imprevistos de maior durante o desenvolvimento e o autor conseguisse o desenvolvimento dos mesmos, representam uma mais valia para o projeto. 23 Capítulo 5 Definição da Aplicação Neste capítulo está apresentada a arquitetura do sistema. Primeiro uma visão mais generalista de como funciona todo o sistema de análise de vulnerabilidades e, depois, uma visão mais precisa e profunda de como funcionará o parser proposto nesta dissertação e o modo como interagirá com o atual motor de análise de vulnerabilidades. Estão presentes, ainda, algumas especificações e exemplos da gramática do parser, de modo a facilitar a perceção dos mesmos por parte do leitor. Já a sua versão completa está presente no anexo F. 5.1 Arquitetura do Sistema A arquitetura do sistema está dividida em duas subsecções. Na primeira é apresentada uma visão geral da arquitetura existente do CodeV, enquanto que na segunda é explicada mais pormenorizadamente a arquitetura do parser a implementar. Esta interage com o produto já existente, e que tipo de dados recebe e fornece. 5.1.1 Visão Geral Na figura 5.1 está demonstrada a arquitetura, num modelo mais global, do funcionamento do CodeV. Para usar a aplicação o utilizador apenas necessita de possuir um aparelho eletrónico (computador fixo, portátil, smartphone, tablet, etc) capaz de se conectar ao servidor existente através de um browser (ligação por https). Todo o código deve ser compactado antes para um ficheiro no formato “.zip”, só depois enviado para o servidor. Já dentro do CodeV é descomprimido o ZIP para uma pasta do sistema. De seguida o motor de análise de vulnerabilidades, para cada ficheiro de código fonte existente no projeto, invoca o parser indicando o ficheiro a ser analisado. Após efetuar o parsing do ficheiro o parser retorna a AST referente ao motor de análise de vulnerabilidades 1 . Por sua vez e, após obter todas as ASTs, o motor de análise procura vulnerabilidades existentes nas ASTs. A cada vulnerabilidade encontrada vai completando o relatório, adicionando informação à base de dados, ficando o relatório armazenado no servidor para ser consultado mais tarde em qualquer momento. 1é gerada uma AST para cada ficheiro de código fonte 24 Luís Laranjeira - PJMAS DESKTOP AST Code Files HTTPS ZIP Parser Motor Análise Vulnerabilidades HTTPS LAPTOP CodeV HTTPS HTML Base Dados TABLET Legenda Comunicação unidirecional Comunicação bidirecional Comunicação com o Parser Figura 5.1: Visão Global da Arquitetura da Aplicação. Por fim, para mostrar o resultado final do relatório ao utilizador numa forma percetível é gerado HTML com todas as informações referentes à análise efetuada ao projeto e, seguidamente, enviado o respetivo HTML para o utilizador. Mais tarde, e sempre que o utilizador pretenda visualizar o relatório sobre o teste, basta aceder à plataforma online através de qualquer dispositivo (tal como anteriormente), e consultar o projeto submetido. 5.1.2 Visão Detalhada do Parser A figura 5.2 apresenta uma visão mais detalhada dos processos que acontecem na área sombreada a verde na figura 5.1 representando os processos que interagem diretamente com o parser a criar pelo autor nesta proposta de dissertação. Tal como referido na subsecção anterior, é recebido um arquivo zip com todos os ficheiros a serem analisados pela aplicação. O diagrama de estados apresentado corresponde às seguintes ações: • Após submissão de um novo projeto um Middleware extrai todos os ficheiros contidos no arquivo zip para uma pasta do sistema. • É informado o motor de análise de vulnerabilidades que existe um novo projeto a ser analisado, indicando a pasta onde foi guardado o projeto descomprimido. • Após determinados os ficheiros do projeto que correspondem a código fonte, é invocado o parser correspondente (PHP ou Java), enviando como parâmetro um objeto do tipo File, com a localização de um ficheiro de código. 25 Luís Laranjeira - PJMAS Submissão novo Projeto Descomprimir Projeto entry/Detectar ZIP do/Descomprimir ZIP para pasta no sistema Projeto Descomprimido Determinar Ficheiros Código Fonte entry/localizar ficheiros do projeto do/listar ficheiros a analisar ficheiros definidos análise terminada Análise Vulnerabilidades do/Análise às AST's do/Gerar Relatório AST's Geradas Gerando AST's entry/Abrir Ficheiro do/Parsing Ficheiro exit/Fechar FIcheiro novo ficheiro (n) Legenda Estado Inicial Estado Final Transição de estado Figura 5.2: Diagrama de estados representativo da análise de um projeto. • O parser “abre” o ficheiro de código fonte indicado, efetuando o parsing e criando a AST respetiva lendo os Tokens diretamente do ficheiro, sendo este “fechado” apenas após o parsing concluído. • É retornado ao motor de análise de vulnerabilidades um objeto contendo a AST gerada e o objeto File recebido como parâmetro. • Após todas as ASTs geradas é analisado o seu conteúdo pelo motor de análise de vulnerabilidades, sendo o relatório construido em simultâneo à análise. 5.2 Gramática do Parser A gramática do parser representa toda a arquitetura deste, os seus estados e transições. A gramática completa do parser está presente no anexo F. Seguidamente serão explicados alguns exemplos de modo a que o leitor consiga compreender com facilidade os termos em que a gramática foi documentada. Para a construção da gramática o autor seguiu regras de expressões regulares, utilizando assim as mesmas para atribuir propriedades aos estados, como será percetível nos exemplos apresentados. Como as notações EBNF utilizam igualmente expressões regulares, notações essas que por sua vez são usadas para escrever o código no parser selecionado (JavaCC), a gramática acaba assim por ser uma aproximação ao parser final e uma ajuda importante para a sua construção. 26 Luís Laranjeira - PJMAS 5.2.1 Construção da Gramática A gramática do parser foi construída tendo em atenção a constituição da gramática existente para a linguagem PHP, consultando igualmente a especificação da linguagem Java [25] e das JSP [26]. A necessidade de ter atenção à constituição da gramática do parser de PHP está relacionada com o requisito não funcional AST Gerada Compatível com a Plataforma Existente, apresentado anteriormente no capítulo 4.2.1. Quanto mais similares forem as gramáticas, mais similares serão as ASTs resultantes do parsing2 e em consequência, menor será o esforço/complexidade necessário para configurar o motor de análise de vulnerabilidades, de modo a suportar o novo módulo desenvolvido e detetar vulnerabilidades em código fonte Java. A construção de uma gramática especifica acarretou uma dificuldade acrescida, pois foi necessário ter em conta todas as combinações lexicais possíveis e, ao mesmo tempo, garantir que não existiam muitas ambiguidades (evitar LOOKAHEAD), de modo a não comprometer a performance do parser. Caso contrário seria utilizada uma gramática já existente e alterado apenas o conteúdo dos nós, não tendo o autor que criar a gramática. Para além da gramática ser especifica para o CodeV, combina as especificações da linguagem Java e das JSP, tal como o leitor pode observar no anexo F. O autor estudou e analisou as vastas opções das JSP, nomeadamente quando pode ser inserido código fonte Java nas mesmas e viceversa, combinando as duas especificações de forma funcional no parser e permitindo aceitar as combinações entre as especificações na sua totalidade. Embora a gramática tenha sido criada antes da implementação foram efetuadas diversas alterações durante o processo de desenvolvimento do parser, causadas por problemas e/ou melhorias melhorias detetadas, estando as mesmas documentadas no capítulo 6. 5.2.2 Expressões Regulares Expressão ∗ + ? | Significado O elemento anterior ao símbolo é adicionado à sequência Zero ou mais vezes O elemento anterior ao símbolo é adicionado à sequência uma ou mais vezes O elemento anterior ao símbolo, é ignorado ou adicionado à sequência uma vez É adicionado à sequência, ou o elemento anterior, ou o elemento posterior ao símbolo Exemplo a* := “ ”,“a”,“aaaa” b+ := “b”, “bbbbb” ab?c := ”abc”, “ac” (a|c)d := “ad”, “cd” Tabela 5.1: Expressões Regulares Utilizadas na Gramática Na tabela 5.1 estão presentes todas as expressões regulares utilizadas na construção da gramática para o parser proposto na atual dissertação. De seguida estão apresentados alguns exemplos da gramática, de modo a que o leitor perceba na totalidade a gramática criada para o parser. 2 Combinações possíveis entre os nós parecidas. 27 Luís Laranjeira - PJMAS 5.2.2.1 Exemplo 1: ASTRoot ASTRoot := Statement* Neste primeiro exemplo é identificado o primeiro estado de todo o “parsing”, o ASTRoot, em cada ASTRoot, é possível expandir para Statement*, isto significa, que como nós de ASTRoot poderá existir 0, 1, .. n estados Statement. Por exemplo, supondo que o código fonte fosse um ficheiro JSP vazio, ter-se-ia então ASTRoot = “ ”, e terminaria assim o parsing do ficheiro. Caso fosse composto apenas por código HTML, seguindo os requisitos funcionais, deveria ser identificado como uma função “print” em Java, ou seja, ASTRoot = Statement. 5.2.2.2 Exemplo 2: Statement Statement := SelectionStatement | ExpressionStatement | IncludeStatement | PageIncludeStatement | DefineStatement | CompoundStatement | EchoStatement | IterationStatement | JumpStatement | LabeledStatement | ClassDeclaration Para cada Statement existem várias opões, mais precisamente 11 possibilidades, sendo que atingindo um estado destes, é necessário sempre continuar para uma das opções. Continuando o exemplo anterior em 5.2.2.1, e sabendo à partida que o estado que corresponde à função “print” do java é o EchoStatement, o seguimento do exemplo seria Statement = EchoStatement. 5.2.2.3 Exemplo 3: AssignmentExpression AssignmentExpression := (Variable | PostfixExpression) AssignmentOperator (CastExpression | AdditiveExpression | PostfixExpression | ClassInstantiation | Constant PostfixIncDecExpression) Já no exemplo 3 temos uma solução mais complexa. Neste estado, existe uma escolha entre os estados Variable e PostfixExpression, que serão seguidos pelo estado AssignmentOperator, que por sua vez,terá um dos restantes 5 estados - AssitiveExpression, PostfixExpression, ClassInstantiation, ou Constant e PostfixIncDecExpression - à sua direita. Uma dependência do estado AssignmentExpression poderá ser, por exemplo, AssignmentExpression = Variable AssignmentOperator ClassInstantiation. Assim, vão sendo expandidos os estados, de modo a formar a AST. 28 Luís Laranjeira - PJMAS 5.3 Parsing do Código Como referido anteriormente, o gerador de parsers escolhido efetua o parsing do código fonte utilizando um algoritmo top-down. Neste capítulo, será exemplificado o parsing de um pedaço de código simples, já com a gramática do parser apresentada no capítulo 5.2, de forma a explicar o funcionamento do mesmo. 5.3.1 Top-Down Parsing No parsing top-down, a árvore do parser é determinada a partir da raiz, no projeto PJMAS corresponde ao nó ASTRoot, construindo a árvore de forma descendente até aos nós terminais. Em cada nó, visto poderem existir várias possibilidades, são selecionados os Tokens mais importantes, que possibilitam diferenciar as possibilidades diferentes, e é feita a escolha seguindo esses caracteres. Esta abordagem pode trazer alguns problemas caso existam nós que sejam identificados pelo mesmo conjunto de caracteres, gerando assim uma ambiguidade na gramática. O algoritmo de parsing utilizado pelo JavaCC é o LL(k) que, como referido anteriormente no capítulo 3.4.2, permite a especificação do valor de lookahead(k) contornando, deste modo, o problema identificado. Assim, são verificados os tokens seguintes até ao limite especificado e encontrada a solução correta, resolvendo a ambiguidade. Por default o valor de lookahead é 1, podendo ser alterado para uma função ou parte especifica do código. No entanto, é de evitar a utilização excessiva desta funcionalidade com um valor de lookahead elevado, e deve-se construir a gramática o menos ambígua possível, pois o uso de lookahead aumenta bastante a complexidade do parser, exige mais processamento por parte do Central processing unit (CPU), mais memória utilizada e, consequentemente, mais tempo para analisar o ficheiro. 5.3.2 Exemplo ASTRoot Statement ExpressionStateement AssignmentExpression Variable AssignmentOperator additiveExpression Constant int a = 4 constant + 5 ; Figura 5.3: Árvore resultante da expressão “int a = 4 + 5 ;” 29 Luís Laranjeira - PJMAS Na figura 5.3 está representada a árvore resultante do parsing de um ficheiro apenas com a linha de código “int a = 4 + 5 ;”. Estando na figura 5.4 representada a ordem que os mesmos são selecionados/criados. Para a construção deste exemplo foi utilizada a gramática criada para o parser, presente no anexo F, que será implementado no decorrer do segundo semestre. 1 2 3 4 5 8 10 11 6 7 9 12 14 13 15 16 Figura 5.4: Ordem em que os nós são selecionados/criados Como é possível verificar na figura 5.4 pela ordem dos nós visitados apresentada, é efetuado o parsing começando na raiz, visitando sempre primeiro os nós mais à esquerda, de modo a identificar primeiro os tokens mais à esquerda. 30 Capítulo 6 Implementação Neste capítulo estão apresentadas as várias funcionalidades implementadas, assim como alguns dos problemas com que o autor se deparou no desenvolvimento e a forma como ultrapassou os mesmos. 6.1 Estados Lexicais Uma das especificações lexicais que o JavaCC permite utilizar são os estados lexicais[27]. Em cada estado lexical é possível definir reserved Tokens, identificação de Tokens e/ou regras independentes, o que para o projeto é bastante importante visto que, por exemplo, os reserved Tokens da linguagem Java são diferentes dos utilizados nos JSP. Na figura 6.1 estão apresentados os estados lexicais definidos no parser desenvolvido. O objetivo da criação dos vários estados é eliminar possíveis erros derivados dos reserved Tokens e da identificação de Tokens ser diferente em cada um dos estados. Os conjuntos apresentados na figura correspondem aos seguintes Tokens: • C1 é composto por todos os Tokens presentes na gramática, excluindo “package”, “import”, “class”, “enum”, “@interf ace”, Tokens presentes da expansão Modifier e Annotation (presentes na gramática do Parser); • C2 é composto pelos Tokens “< jsp : directive.”, “< jsp :”, “< %@”, “< /jsp : directive.” e “< /jsp :”; • C3 contém os Tokens “% >”, “/ >”, “>”; • C4 contém os Tokens “< jsp : scriptlet >”, “< jsp : declaration >”, “< jsp : expression >”, “< %”, “< %@” e “< %!”; • Já C5 é constituído pelos Tokens “% >”, “< /jsp : declaration >”, “< /jsp : expression >” e “< /jsp : scriptlet >”. O estado lexical DEFAULT é o primeiro estado utilizado, este estado é representativo da linguagem Java. Caso o ficheiro a ser analisado contenha unicamente código fonte Java é utilizado apenas este estado no parsing do ficheiro. Para determinar se é de facto um ficheiro de código fonte Java, ou um JSP, é efetuado um “lookahead”, de forma a verificar se os primeiros Tokens detetados correspondem ao esperado 31 Luís Laranjeira - PJMAS '%>' RTATTRIBUTE _STATE JSP_JAVA '<%=' ' ' ' ou ' " ' C4 C5 ' ' ' ou ' " ' C3 start DEFAULT HTML_STATE C1 JSP_STATE C2 '--%>' <EOF> ' ' ' ou ' " ' <EOF> '<%--' JSP_COMME NT ' ' ' ou ' " ' JSP_IMPORT _STATE end Legenda Transição de Estado Cn Conjunto de Tokens que possibilitam transição Figura 6.1: Estados Lexicais do Parser e Transições. para a linguagem Java. Caso a condição não se verifique, é efetuada uma transição para o estadoHTML STATE. O estado HTML STATE representa o HTML e é utilizado, como o nome indica, nas “partes” do JSP em que é detetado HTML, Como tokens definidos têm os presentes nos conjuntos C2, C4 e ’< % − −’, que representam as transições para outros estados lexicais. O estado JSP COMMENT é utilizado ao detetar comentários nos JSP, neste caso todos os caracteres são ignorados até encontrar o Token ’− − % >’, que permite regressar ao estado HTML STATE. Já o estado JSP JAVA contém todas as caraterísticas/propriedades do estado DEFAULT, com a diferença que contempla mais Tokens definidos, como é o caso dos Tokens do conjunto C5. Um exemplo prático da necessidade de implementação de estados diferentes para este caso está presente no seguinte excerto de código fonte, podendo-se encontrar quer num ficheiro Java, quer num JSP: 32 Luís Laranjeira - PJMAS (...) / / comentá r i o com %> (...) Excerto 6.1: Código exemplificativo de possível análise incorreta do parser No excerto acima apresentado, com o mesmo código, o parser necessita de obter comportamentos diferentes, caso se trate de um ficheiro de código fonte Java é necessário trata-lo como um simples comentário, no entanto, caso se trate de um ficheiro JSP, ao detetar o Token ’% >’ o parser deve reconhecer que terminou o pedaço de código Java, e que de seguida deve retornar ao estado HTML STATE. De salientar que ao detetar o token acima referido (’% >’), é igualmente possível retornar ao estado RTATTRIBUTE STATE. Embora seja o mesmo token, é detetado em contextos diferentes e, por isso, é possível indicar transições para estados diferentes. O estado JSP STATE foca-se nas declarações do tipo XML1 que são utilizadas nos documentos JSP, sendo os reserved tokens deste estado, as vastas propriedades possíveis de declarar através das expressões referenciadas. As transições quer para o estado RTATTRIBUTE STATE, quer para o estado JSP IMPORT STATE são efetuadas através dos Tokens ’ ” ’ ou ’ 0 ’, alterando para um dos dois estados consoante o contexto em que se encontre o parsing do ficheiro, caso se trate de import de ficheiro2 , o estado a transitar é o JSP IMPORT STATE, caso contrário, transitará para o estado RTATTRIBUTE STATE. Já no estado JSP IMPORT STATE, é um estado bastante simples do ponto de vista de especificações, detetando apenas os Tokens como constantes, virgulas (’ , ’), e aspas ou parêntesis (’ 0 ’, ’ ” ’), sendo estes dois últimos os Tokens que possibilitam nova transição de estado. Para atribuição de valores nas restantes propriedades, é utilizado o estado RTATTRIBUTE STATE. Ao contrário do estado anterior, para além de identificar os tokens como constantes, também identifica a tag de inicio de uma JSP Expression (’< % =’), alterando o estado para JSP JAVA, por forma a começar a identificação de Tokens Java. 6.2 Alteração dos Ciclos for na AST O presente requisito funcional, apresentado no capítulo 4.1.3, tinha como objetivo substituir os ciclos “for” por ciclos “while” na AST com o propósito de diminuir a complexidade e, em consequência, o tempo necessário para análise de vulnerabilidades no código fonte. De seguida será apresentado um exemplo com código fonte da transformação operada na AST, para melhor perceção do leitor. (...) for ( String str : arr ) { System . out . p r i n t l n ( s t r ) ; } (...) Excerto 6.2: Código fonte original. 1 Por 2 Por exemplo: <jsp:param name=“variable” value=“Home” />. exemplo: import="javax.naming.*, java.text.SimpleDateFormat" 33 Luís Laranjeira - PJMAS O excerto 6.2 representa o código fonte original que pode ser encontrado em código fonte Java, ao qual pode ser aplicada a alteração. (...) i n t i t e r a t i o n 0 =0; while ( i t e r a t i o n 0 <a r r . s i z e ( ) ) { S t r i n g s t r=a r r . get ( i t e r a t i o n 0 ) ; System . out . p r i n t l n ( s t r ) ; i t e r a t i o n 0 ++; } (...) Excerto 6.3: Código fonte correspondete. Já o excerto 6.3, equivalente ao excerto 6.2, representa os nós presentes na AST após alteração da mesma. Inicialmente o autor começou por implementar a modificação dos ciclos no decorrer do parsing, ou seja, logo após a deteção do ciclo na gramática. No entanto, tal não foi possível efetuar devido a propriedades do JavaCC. Como o leitor pode observar analisando a gramática no anexo F, as produções referentes a “expressões” que combinam objetos (soma, multiplicação, variáveis, comparações, incrementações, etc) derivam todas da produção ExpressionStatemen, estando todas encadeadas. Para a árvore não se tornar tão extensa o autor utilizou uma especificação do JavaCC que remove o nó selecionado, caso não tenha determinado atributo. Por exemplo, na produção Logical_Or_Expression:= Logical_And_Expression ( “||” Logical_Or_Expression )? o autor definiu que caso não seja detetado o Token “||” , o presente nó é removido da AST, automaticamente, pelo JavaCC. Esta opção acaba por remover bastantes nós sem conteúdo. O problema é que o JavaCC não efetua tal ação no imediato, ou seja, ao aceder à AST na produção em que é detetado o ciclo, os nós filhos não possuem qualquer conteúdo viável, pelo que se torna bastante complicado efetuar qualquer alteração de fundo durante o parsing do código fonte. No entanto, é possível efetuar tal alteração após a AST ser gerada, percorrendo a árvore e modificando os nós específicos quando detetados. Foram apresentados os detalhes do problema e a solução proposta pelo autor (alterar após a AST completa) à entidade acolhedora, que aprovou a solução. Para quem utilizar o parser (no presente projeto, o CodeV), o processo é completamente transparente, necessitando apenas de especificar se pretende que os ciclos sejam alterados ou não (por default o parser não procede à sua modificação). Caso o utilizador pretenda a alteração dos ciclos, esta é efetuada antes de retornar a AST. A desvantagem da solução adotada é o decréscimo de performance do parser, pois necessitará de percorrer toda a árvore novamente antes de a retornar. Foi feita uma breve análise à diferença de performance registada, que pode ser visualizada na tabela 6.1. linhas de código 1323642 Total s/ alteração (ms) 8502 Total c/ alteração (ms) 15458 Tabela 6.1: Comparação entre tempo de parsing com alterações e sem alterações aos ciclos A tabela 6.1 apresenta o tempo total que o parser demorou a efetuar o parsing a todos os ficheiros de código fonte do projeto Eclipse JDK Core Component[5]. Tal como referido 34 Luís Laranjeira - PJMAS anteriormente, a performance do parser diminui significativamente. No entanto trata-se de uma opção que o utilizador pode usar ou não. No anexo G.1.3 o leitor pode observar os testes efetuados à funcionalidade, que são um bom auxílio para uma melhor perceção das alterações efetuadas. 6.3 Extensão de Anotações Ao contrário do que foi definido na análise de requisitos não foi possível efetuar a extensão de anotações no parser, pois, após análise do correto funcionamento das anotações, foi detetado que são tratadas através de processadores ao compilar a aplicação. Mesmo as anotações criadas e definidas pelo próprio programador necessitam de um processador de anotações, ou caso contrário não terão efeito prático. Para o autor a partir da análise do parser, detetar o ficheiro onde são processadas as anotações e verificar que operações são efetuadas, tornou-se numa missão incomportável de desenvolver durante o presente estágio, pelo que o requisito foi descartado para desenvolvimento imediato, com o consentimento e aprovação da entidade acolhedora. 6.4 Extensão Múltiplos Exceptions nos Catch do JDK 1.7 O presente requisito funcional tinha como objetivo a expansão dos catch múltiplos no código fonte Java. De seguida está exemplificada em código a funcionalidade desenvolvida. try { i n = new F i l e I n p u t S t r e a m ( path ) ; J a v a P a r s e r j p=new J a v a P a r s e r ( i n ) ; SimpleNode sn=j p . parse ( ) ; } catch ( IOException | ParseException e ) { e . printStackTrace ( ) ; return false ; } Excerto 6.4: Exemplo Try-Catch com Catch múltiplo. No excerto 6.4 está presente um exemplo simples do uso de um catch com a variável e a ter 2 objetos distintos. try { i n = new F i l e I n p u t S t r e a m ( path ) ; J a v a P a r s e r j p=new J a v a P a r s e r ( i n ) ; SimpleNode sn=j p . parse ( ) ; } catch ( IOException e ) { e . printStackTrace ( ) ; return false ; } catch ( ParseException e ) { e . printStackTrace ( ) ; return false ; } Excerto 6.5: Exemplo Try-Catch com Catch múltiplo após extensão. No excerto 6.5 é possível observar o código fonte correspondente ao excerto 6.4 após a alteração efetuada na AST. É então criado um novo catch para cada tipo de erro diferente 35 Luís Laranjeira - PJMAS existente, sendo os nós correspondentes ao código fonte a executar pelo catch replicados para todos os novos nós gerados. Após a alteração efetuada cada variável tem apenas um tipo de objeto associado, removendo assim o problema detetado na análise de vulnerabilidades. 6.5 Alterações à AST nas JSP No presente capítulo estão apresentadas as alterações efetuadas aos nós da AST definidos no capítulo 6.5. As alterações efetuadas consistem em modificar os nós correspondentes a declarações no formato XML presentes nas JSP em código fonte Java. 6.5.1 GetProperty A tag < jsp : getP ropertyname =00 property =00 é mais uma alternativa de apresentação de dados na aplicação ao dispor do programador. Sendo os dados apresentados aos utilizadores importantes na análise de vulnerabilidades, e estando o CodeV configurado/preparado para verificação de objetos/variáveis a partir de combinações de nós da AST de forma diferente (linguagem Java, PHP), o autor em conformidade com o orientador Hugo Trovão decidiu alterar os nós da AST para o código correspondente à mesma função na linguagem Java. As alterações efetuadas poderão ser visíveis no exemplo demonstrado de seguida. (...) <j s p : g e t P r o p e r t y name=" u s e r " p r o p e r t y= ’ name ’ /> (...) Excerto 6.6: Código exemplificativo da utilização da tag jsp:getProperty No excerto 6.6 está exemplificada uma chamada à tag referida anteriormente, apresentando de seguida as respetivas AST referentes ao código fonte exemplificado. (...) . JspPage /> . . JspTagStatement /> . . . J s p S t a n d a r d A c t i o n echo . . . . JspStandardActionGetProperty ’ . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s name . . . . . . AttributeValue [ user ] . . . . . JspStandardActionParameters property . . . . . . A t t r i b u t e V a l u e [ name ] (...) Excerto 6.7: AST resultante antes da modificação O excerto 6.7 representa o pedaço da AST referente ao excerto de código apresentado acima antes de modificações efetuadas na AST. 36 Luís Laranjeira - PJMAS (...) . JspPage /> . . JspTagStatement /> . . . J s p S t a n d a r d A c t i o n echo . . . . ArgumentExpressionList . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . Variable Variable : : user " n u l l " . . . . . . V a r i a b l e V a r i a b l e : : name " n u l l " (...) Excerto 6.8: AST resultante após modificação Já o excerto 6.7 representa a AST após as modificações efetuadas. As modificações, tal como referido anteriormente e visível nos dois excertos anteriores, substitui nós referentes a deteção de declarações no formato XML nas JSP por nós equivalentes da linguagem Java. Quer isto dizer que são substituidos os nós originais por nós que representam a mesma função na linguagem Java (que existiam igualmente para a linguagem PHP e para os quais o motor de análise de vulnerabilidades já se encontra preparado, diminuindo assim a complexidade de integração/configuração do CodeV. As alterações são efetuadas durante o parsing do ficheiro, não afetando desta forma a performance do parser de forma significativa. Para alteração dos nós da AST referentes às JSP foi criada uma variável configurável no parser antes do início da análise do ficheiro, que define se a AST é modificada ou não. 6.5.2 SetProperty Tal como a Tag descrita no capítulo anterior, a Tag < jsp : setP roperty > utiliza declaração de dados no formato XML. O propósito da presente modificação é o mesmo da anterior, alterar alguns nós da AST para outros que correspondam à mesma funcionalidade mas que o CodeV reconhece para análise de vulnerabilidades. A Tag apresentada permite ao programador atribuir valores a objetos e às suas variáveis, podendo efetuar o mesmo com várias propriedades diferentes. De seguida está descrito um exemplo do funcionamento da alteração da AST. (...) <j s p : s e t P r o p e r t y p r o p e r t y=" name " name=" u s e r " v a l u e=" L u i s " /> <j s p : s e t P r o p e r t y name=" u s e r " p r o p e r t y=" name " v a l u e="<%=name%> " /> <j s p : s e t P r o p e r t y param=" i d " p r o p e r t y=" name " name=" u s e r " /> (...) Excerto 6.9: Código exemplificativo da utilização da tag jsp:setProperty No excerto 6.9 estão apresentados três exemplos do uso da da Tag < jsp : setP roperty/ >, em que é atribuído um valor à variável “name” pertencente ao objeto inicializado como “user”. A propriedade “value” pode ser uma constante (caso 1), qualquer valor retornado por operações na linguagem Java (caso 2), ou atribuir diretamente o valor recebido como parâmetro3 pela página (caso 3). 3 Parâmetros recebidos quer por get e/ou post. 37 Luís Laranjeira - PJMAS (...) . JspPage /> . . JspTagStatement /> . . . JspStandardAction setProperty . . . . JspStandardActionSetProperty " . . . . . JspStandardActionParameters property . . . . . . A t t r i b u t e V a l u e [ name ] . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s name . . . . . . AttributeValue [ user ] . . . . . JspStandardActionParameters value . . . . . . AttributeValue [ Luis ] . JspPage /> . . JspTagStatement /> . . . JspStandardAction setProperty . . . . JspStandardActionSetProperty " . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s name . . . . . . AttributeValue [ user ] . . . . . JspStandardActionParameters property . . . . . . A t t r i b u t e V a l u e [ name ] . . . . . JspStandardActionParameters value . . . . . . A t t r i b u t e V a l u e [ E x p r e s s i o n S t a t e m e n t name ] . . . . . . . E x p r e s s i o n S t a t e m e n t name . . . . . . . . V a r i a b l e V a r i a b l e : : name " n u l l " . JspPage /> . . JspTagStatement /> . . . JspStandardAction setProperty . . . . JspStandardActionSetProperty " . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s param . . . . . . AttributeValue [ id ] . . . . . JspStandardActionParameters property . . . . . . A t t r i b u t e V a l u e [ name ] . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s name . . . . . . AttributeValue [ user ] (...) Excerto 6.10: AST resultante antes da modificação No excerto 6.10 está apresentada a AST resultante do parsing do ficheiro correspondente ao excerto de código 6.9, é possível verificar a deteção dos vários parâmetros presentes no código fonte. (...) . JspPage /> . . JspTagStatement /> . . . JspStandardAction setProperty . . . . AssignmentExpression . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . Variable Variable : : user " n u l l " . . . . . . V a r i a b l e V a r i a b l e : : name " n u l l " . . . . . AssignmentOperator Operator : : = . . . . . Constant Constant : : s t r i n g : : L u i s . JspPage /> . . JspTagStatement /> . . . JspStandardAction setProperty . . . . AssignmentExpression . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . Variable Variable : : user " n u l l " . . . . . . V a r i a b l e V a r i a b l e : : name " n u l l " 38 Luís Laranjeira - PJMAS . . . . . AssignmentOperator Operator : : = . . . . . E x p r e s s i o n S t a t e m e n t name . . . . . . V a r i a b l e V a r i a b l e : : name " n u l l " . JspPage /> . . JspTagStatement /> . . . JspStandardAction setProperty . . . . AssignmentExpression . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . Variable Variable : : user " n u l l " . . . . . . V a r i a b l e V a r i a b l e : : name " n u l l " . . . . . AssignmentOperator Operator : : = . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . Variable Variable : : request " n u l l " . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . V a r i a b l e V a r i a b l e : : getParameter " n u l l " . . . . . . . ArgumentExpressionList . . . . . . . . Constant Constant : : s t r i n g : : i d (...) Excerto 6.11: AST resultante após modificação Já no excerto 6.11, está apresentada a AST relativa ao mesmo código fonte, mas após as alterações efetuadas no parser. As alterações são efetuadas no decorrer do parsing, não afetando assim a sua performance. A alteração efetuada à AST, tal como a do subcapítulo anterior, está dependente de uma variável booleana configurável, podendo o utilizador do parser decidir conforme a sua necessidade. 6.5.3 Beans Os Beans são uma propriedade das JSP bastante utilizada pelos programadores em JavaEE/J2EE. São principalmente utilizados para definir/identificar clientes da aplicação e propriedades relacionadas com os mesmos que sejam importantes para a aplicação. Tal como os casos anteriormente apresentados, utiliza igualmente declarações no formato XML para definição dos mesmos. Como são um propriedade importante e bastante utilizada pela comunidade, o autor em conjunto com o Orientador da entidade acolhedora Eng. Hugo Trovão, decidiram alterar igualmente a AST neste ponto especifico. Como no fundo, um Bean é um objeto Java, foi definido que os nós da AST devem corresponder à inicialização de uma variável/objeto da mesma forma que acontece em código fonte Java. (...) <j s p : useBean i d=" u s e r " c l a s s=" J s p U s e r . User " scope=" page " /> (...) Excerto 6.12: Código exemplificativo da utilização da tag jsp:useBean No excerto 6.12 está presente uma declaração de um Bean, sendo um objeto do tipo “JspUser.user”. O nome atribuído à variável (Bean) é “user”. (...) . JspPage /> . . JspTagStatement /> . . . J s p S t a n d a r d A c t i o n useBean . . . . JspStandardActionUseBean " 39 Luís Laranjeira - PJMAS . . . . . . . . . . . . ... ... ... ... ... ... JspStandardActionParameters id . AttributeValue [ user ] JspStandardActionParameters c l a s s . A t t r i b u t e V a l u e [ J s p U s e r . User ] J s p S t a n d a r d A c t i o n P a r a m e t e r s scope . A t t r i b u t e V a l u e [ page ] (...) Excerto 6.13: AST resultante antes da modificação No excerto acima acima apresentado é possível verificar como são detetados os três atributos declarados no excerto 6.12 (user, JspUser.User e page). (...) . JspPage /> . . JspTagStatement /> . . . J s p S t a n d a r d A c t i o n useBean . . . . V a r i a b l e V a r i a b l e : : o b j e c t : : u s e r " C l a s s : : J s p U s e r . User ( , ) " (...) Excerto 6.14: AST resultante após modificação Como é visível nos excertos 6.12, 6.13 e 6.14, após a alteração da AST, os nós detetados anteriormente são combinados no nó “Variable”. Mais uma vez, esta alteração é efetuada durante o parsing do código fonte e pode ser ativada/desativada conforme o utilizador pretenda. 6.5.4 Include e Forward A utilização das Tags < jsp : f orwardpage => e < jsp : includepage => é bastante semelhante, utilizando ambas os mesmos parâmetros, a diferença está na sua utilidade. Enquanto que a primeira efetua redirecionamento para outra página, a segunda inclui a página definida no própria página. A alteração efetuada na AST foi igual para ambos os casos, apenas diferindo no tipo, Include ou Forward. (...) <j s p : i n c l u d e page=" NewFile . j s p " /> <j s p : f o r w a r d page=" O l d F i l e . j s p "> </ j s p : forward > (...) Excerto 6.15: Código exemplificativo da utilização da tag jsp:include e jsp:forward No excerto 6.15 está presente uma declaração com Include e outra com Forward, sendo a página de destino diferente. (...) . JspPage /> . . JspTagStatement /> . . . JspStandardAction Include : : include . . . . JspStandardActionInclude " . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s page . . . . . . A t t r i b u t e V a l u e [ NewFile . j s p ] 40 Luís Laranjeira - PJMAS . JspPage > . . JspTagStatement > . . . JspStandardAction Include : : forward . . . . JspStandardActionInclude " . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s page . . . . . . AttributeValue [ OldFile . jsp ] . . . . RequestArguments . . . . . JspPage . . . . . . HtmlBlock HtmlBlock : : (...) Excerto 6.16: AST resultante antes da modificação No excerto 6.16 está apresentada a AST gerada antes da modificação. As zonas identificadas com a cor amarelo representam as propriedades das Tags referidas neste subcapítulo. (...) . JspPage /> . . JspTagStatement /> . . . JspStandardAction Include : : include . . . . Constant Constant : : s t r i n g : : NewFile . j s p . JspPage > . . JspTagStatement > . . . JspStandardAction Include : : forward . . . . Constant Constant : : s t r i n g : : O l d F i l e . j s p . . . . RequestArguments . . . . . JspPage . . . . . . HtmlBlock HtmlBlock : : (...) Excerto 6.17: AST resultante após modificação Já no excerto 6.17 estão apresentados os nós da AST correspondentes ao mesmo código fonte. De referir que a zona sombreada a verde corresponde à zona sombreada a amarelo no excerto 6.16. 6.6 Melhorias à Performance do Parser Ao longo do desenvolvimento do parser existiram cuidados no sentido de manter a performance do mesmo a um nível aceitável, principalmente tentando sempre evitar ao máximo os lookaheads, mas respeitando os nós (produções) da gramática pré-definida. Após o parser desenvolvido, o autor fez uma revisão e alterou várias produções da gramática tendo, assim, melhorado significativamente o performance do parser. A revisão incidiu principalmente na redução dos valores de LOOKAHEAD utilizados, mas mantendo o seu perfeito funcionamento. A alteração mais significativa foi efetuada na produção PostfixExpression, visto ser um dos nós mais utilizados no parsing de ficheiros pelo parser desenvolvido. SimpleNode P o s t f i x E x p r e s s i o n ( ) : {} { Primary ( ) ( (LOOKAHEAD( P o s t f i x E x p r e s s i o n ( ) ) P o s t f i x E x p r e s s i o n ( ) | V a r i a b l e ( ) | Constant ( ) | ClassInstantiation ( ) ) 41 Luís Laranjeira - PJMAS | ArgumentExpressionList ( ) ( " [ " [ Expression ( ) ] " ] " ) ∗ [ " . " ( LOOKAHEAD( P o s t f i x E x p r e s s i o n ( ) ) P o s t f i x E x p r e s s i o n ( ) | V a r i a b l e ( ) | Constant ( ) | ClassInstantiation ( ) ) ] | ) | ( " [ " [ Expression ( ) ] " ] " ) + [ " . " (LOOKAHEAD( P o s t f i x E x p r e s s i o n ( ) ) P o s t f i x E x p r e s s i o n ( ) | V a r i a b l e ( ) | Constant ( ) | ClassInstantiation ( ) ) ] " ( " Expression ( ) " ) " ( " [ " [ Expression ( ) ] " ] " ) ∗ [ " . " (LOOKAHEAD( 2 ) Q u a l i f i e d I d e n t i f i e r ( ) | Constant ( ) ) ] } Excerto 6.18: Produção inicial PostfixExpression No excerto 6.18 está apresentada a produção postfixExpression antes das melhorias implementadas. Como é possível ao leitor visualizar, existiam algumas invocações de LOOKAHEAD, que verificavam a correspondência do código fonte que se seguia a toda outra produção e suas derivações, como é o caso logo do primeiro LOOKAHEAD(PostfixExpression()). SimpleNode P o s t f i x E x p r e s s i o n ( ) : {} { Primary ( ) ( " . " ( P o s t f i x E x p r e s s i o n ( ) | Constant ( ) ) | ArgumentExpressionList ( ) | ( " [ " [ Expression ( ) ] " ] " ) ) ∗ } Excerto 6.19: Produção final PostfixExpression No excerto 6.19 está presente a mesma produção após as alterações efetuadas. De notar uma grande redução no tamanho da expressão, mas mais importante, a redução no número de LOOKAHEADS, em que passou de 4 para 0. A produção QualifiedIdentifier foi entretanto removida da gramática do parser, e encontradas alternativas mais vantajosas. Versão Parser Antes Otimização Após Otimização Tempo médio (ms) 731.77 472.10 Memória média (MB) 18.95 17.89 Tabela 6.2: Comparação entre performance e memória utilizada antes e depois dos melhoramentos. Na tabela 6.2 estão apresentados os resultados efetuados ao parser antes e após os melhoramentos efetuados. Os testes efetuados utilizaram o ficheiro utilizado anteriormente para comparação dos parsers existentes, capítulo 3.2.1.5, bem como o número de execuções do teste (30 vezes). A tabela com todos os resultados está presente no anexo D. Como é possível verificar, o tempo do parsing diminuiu significativamente após os melhoramentos, reduzindo 259 ms no parsing do ficheiro mencionado. Por outro lado, em termos de memória utilizada, a redução não foi tão significativa, diminuindo cerca de 1MB. 42 Luís Laranjeira - PJMAS 6.7 Iterações de Desenvolvimento No presente capítulo estão apresentadas as iterações de desenvolvimento realizadas para desenvolvimento do projeto PJMAS. A apresentação de cada iteração tem como objetivo ser sucinta e objetiva, indicando em que altura do desenvolvimento esta ocorreu. 6.7.1 Iteração 1 Data: 11 de Março de 2013 → 26 de Março de 2013. Funcionalidades Planeadas: Deteção de comentários, packages, imports, class/enum/interface e variáveis. Implementações Efetuadas: Inicialmente foram definidos todos os reserved tokens da linguagem Java. De seguida foi criada uma expressão regular para identificar e descartar os comentários encontrados no código fonte. Foi então implementada a deteção de packages e de imports, para esta funcionalidade foi necessário especificar já deteção de variáveis e postfixExpression4 . De seguida foram identificadas as declarações de classes, enums e interfaces. Por fim foram detetadas todas as operações possíveis de efetuar entre variáveis e/ou constantes. Foram adicionados atributos nos objetos que preenchem a AST para descrever arrays. Problemas Encontrados: A identificação correta dos comentários causou problemas, não parando de descartar tokens após deteção da condição de paragem quando o comentário continha mais do que 1 asterisco a terminar5 . 6.7.2 Iteração 2 Data: 26 de Março de 2013 → 10 de Abril de 2013. Funcionalidades Planeadas: Deteção de funções, condições, iterações, try-catch e anotações. Implementações Efetuadas: Todas as funcionalidades planeadas foram desenvolvidas com sucesso. O autor criou também um novo objeto para identificação das anotações na AST. Problemas Encontrados: Nenhum problema de maior encontrado. 6.7.3 Iteração 3 Data: 16 de Abril de 2013 → 24 de Abril de 2013. Funcionalidades Planeadas: Deteção de comentários em JSP, HTML, scriptlets, declarations e expressions. Implementações Efetuadas: Foram desenvolvidas todas as funcionalidades planeadas. Cada funcionalidade desenvolvida que tenha mais que um tipo de declaração possível é detetado na mesma produção, ou seja, resultando no mesmo nó. Reduzindo o número de nós diferentes criados para a AST, por exemplo, as declarações scriptlet JSP “<%” e XML “<jsp:scriptlet>”. Foi analisado e definido o mecanismo capaz de detetar se o código fonte analisado é apenas Java ou se é JSP. Problemas Encontrados: Existiram alguns contratempos para definir a transição correta entre código Java e JSP (e vice-versa) nas declarações scriptlet. A razão do mesmo é que as 4 para 5 Por identificação dos ‘.’ entre as variáveis exemplo: /* comment ***/ 43 Luís Laranjeira - PJMAS transições a partir do código fonte Java, caso seja dentro de uma produção compoundStatement 6 , tem que ser definido como filho do mesmo, e tal não acontecia, ou seja, simplesmente retornava ao estado nó pai e ao estado JSP. Foram ainda detetados problemas nos comentários em ficheiros de código fonte Java que continham o token “%>”, pois entrava em colisão com a regra de alterar para o estado JSP, foi solucionado o problema criando um estado novo que se diferencia do código Java em ficheiros Java e em JSP, como está explicado no capítulo 6.1. 6.7.4 Iteração 4 Data: 24 de Abril de 2013 → 6 de Maio de 2013. Funcionalidades Planeadas: Deteção de Directive e Standard Actions em JSP. Implementações Efetuadas: Todas as funcionalidades planeadas foram desenvolvidas com sucesso. Foi criado um novo estado de modo a separar vários imports, inicialmente identificados como uma única constante7 . Problemas Encontrados: Exceto o problema relativo aos imports referido, não foi encontrado nenhum problema de maior. 6.7.5 Iteração 5 Data: 7 de Maio de 2013 → 14 de Maio de 2013. Funcionalidades Planeadas: Alteração de ciclos for e extensão de anotações na AST. Implementações Efetuadas: Foi desenvolvida a alteração de ciclos for, alterando a AST a ordem e conteúdo dos mesmos para que na perspetiva do CodeV seja um ciclo while. Foram implementados 2 algoritmos diferentes, um para ciclos for com 3 identificadores8 e outro para ciclos for para 2 identificadores9 . Problemas Encontrados: Não foi possível desenvolver a extensão de anotações devido à complexidade do processamento das mesmas, explicado mais pormenorizadamente no capítulo 6.3. 6.7.6 Iteração 6 Data: 15 de Maio de 2013 → 22 de Maio de 2013. Funcionalidades Planeadas: Extensão múltiplos Catch do JDK 1.7, alteração de de nós da AST nas JSP e melhorias à performance do parser. Implementações Efetuadas: Os catch múltiplos existentes no JDK 1.7 foram estendidos, aparecendo como nas versões anteriores do JDK na representação da AST. Foram efetuadas algumas alterações na AST de nós correspondentes a declarações no formato XML para nós que correspondam às mesmas funções mas na linguagem Java, reduzindo assim a complexidade de análise de vulnerabilidades de CodeV. Por fim foram reanalisados alguns pontos importantes da implementação e melhorada a performance do parser. Problemas Encontrados: Nenhum foi encontrado nenhum problema significativo. 6 produção que contem, por exemplo, os nós filhos de um ciclo/condição/try-catch exemplo “import = ‘java.io.*, java.util.*’ ”. Entre as plicas era tudo uma constante, foi necessário separar para estes casos específicos. 8 Por exemplo “for(int i=0; i<10; i++)”. 9 Por exemplo “for(String str : arr)”. 7 Por 44 Capítulo 7 Controlo de Qualidade Neste capítulo está presente a metodologia utilizada pelo autor para o controlo de qualidade, os testes efetuados e os resultados obtidos durante o desenvolvimento do parser. 7.1 Abordagem Ao longo do desenvolvimento das várias funcionalidades suportadas pelo parser foram efetuados vários testes unitários, de forma de validarem ou não a respetiva funcionalidade. Cada teste efetuado tem dois resultados possíveis, “Pass” caso o resultado obtido seja o esperado, “Fail” caso o resultado seja diferente. Sempre que o resultado do teste fosse negativo, o “problema” deveria ser corrigido e efetuado o teste novamente, repetindo esta iteração até o resultado observado ser igual ao esperado. Cada funcionalidade foi validada apenas quando todos os testes efetuados retornaram o resultado esperado. Após a implementação de todas as funcionalidades foi efetuado um novo conjunto de testes, divididos em três grupos diferentes. Testes às funcionalidades , analisando vários projetos em JavaEE/J2EE, quer de clientes da entidade acolhedora, quer de projetos “open source”. Estes testes permitiram que o parser fosse testado com aplicações reais, que envolvem um grau de complexidade realista e não fossem apenas ficheiros criados pelo autor. Testes à performance e memória utilizada pelo parser e por fim testes de compatibilidades com o motor de vulnerabilidades. Todos os tipos de testes estão descritos mais pormenorizadamente no subcapítulo 7.2. 7.2 Tipos de Testes Neste subcapítulo são descritos os tipos de testes que foram efetuados para controlo da qualidade do parser, nomeadamente testes às funcionalidades, testes à performance e memória utilizadas pelo parser e testes de integração com o motor de análise de vulnerabilidades. 7.2.1 Testes às Funcionalidades Têm como objetivo validar as funcionalidades implementadas pelo autor. Serão efetuados durante todo o desenvolvimento e são imprescindíveis para a validação de cada funcionalidade. 45 Luís Laranjeira - PJMAS Cada caso de teste consiste no parsing de um ficheiro de código fonte focado principalmente na funcionalidade implementada. Após o parsing do ficheiro é “imprimida” a AST correspondente, bem como o conteúdo de cada nó, para verificação da estrutura e do preenchimento. Embora cada teste se focasse principalmente na funcionalidade implementada, não foram descartadas funcionalidades implementadas anteriormente, garantindo assim compatibilidade com as mesmas. Foi atribuída a classificação pass caso não resultassem erros de parsing e/ou o output fosse igual ao esperado, caso contrário a classificação atribuída foi fail. Sempre que o resultado fosse negativo foi necessário corrigir a funcionalidade e repetir o cunjunto de testes. Só após todos os testes obterem nota positiva é que a funcionalidade foi validada, podendo assim o autor começar a desenvolver a funcionalidade seguinte. Caso em algum dos testes fosse detetado um erro de parsing ou de mau preenchimento da AST numa funcionalidade já validada, causado por alguma incompatibilidade e/ou ambiguidade entre ambas, o autor procedeu à sua correção e, após a mesma, repetiu todos os testes já realizados para ambas as funcionalidades, sendo validadas só após todos os testes terem sido avaliados com nota positiva. Após todas as funcionalidades implementadas, foi executado novamente o presente teste, efetuando parsing de todos os ficheiros de código fonte Java e/ou JSP de projetos de clientes reais da entidade acolhedora e projetos “open source” existentes. O propósito do autor optar por estes testes prendeu-se com a necessidade de testar o parser em aplicações reais, em código fonte que não tenha sido desenvolvido pelo utilizador, de modo a ser o mais próximo da realidade com que o parser se vai deparar no futuro, e que possa conter “combinações” de código que o autor possa não ter testado durante o desenvolvimento do projeto. Nos testes efetuados a projetos foram contemplados apenas os erros de parsing que possam ocorrer, pois para verificar o conteúdo da AST seria um trabalho bastante demorado e complexo. ID Teste: ID-01 Data: 12/03/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Deteção de Imports Descrição: Efetuar parsing do ficheiro exemplo.java Resultado Parsing Esperado: Parsing sem qualquer erro. Resultado Parsing Obtido: Parsing sem qualquer erro detetado. Output observado: ASTRoot IncludeStatement Include::import PostfixExpression PostfixExpression::-> Variable Variable::java "null" PostfixExpression PostfixExpression::-> Variable Variable::util "null" Variable Variable::HashMap "null" Resultado do Teste: Pass. Tabela 7.1: Modelo para testes às funcionalidades. 46 Luís Laranjeira - PJMAS Os testes às funcionalidades foram realizados pelo autor, sendo documentados e analisados posteriormente pelo orientador Eng. Hugo Trovão e/ou outros responsáveis da entidade acolhedora. A tabela 7.1 é representativa do modelo utilizado para os testes, encontrando-se já preenchida com um exemplo para facilitar a perceção da mesma. 7.2.2 Testes à Performance e Memória Após a implementação de todas as funcionalidades do parser completas e devidamente validadas, foram efetuados testes à performance e à memória do parser. Para a realização destes testes foi utilizado o ficheiro dos testes aos parsers existentes que, de certa forma, ajudou a definir os presentes requisitos. Os testes devem respeitar os valores definidos nos requisitos não funcionais, subcapítulo 4.2.2 e subcapítulo 4.2.3. Foi considerado pelo autor e pela entidade acolhedora que o parser apresenta qualidade, nestes dois pontos referidos, caso respeitasse os requisitos não funcionais em, pelo menos, 95% dos testes realizados. Caso os valores observados nos testes não respeitassem os requisitos não funcionais referidos, o autor deveria proceder a uma análise profunda do parser, procurando soluções para melhorar os aspetos que estivessem a falhar. Caso concluísse que não era possível melhoramento dos mesmos, deveriam ser explicadas, detalhadamente, todas as causas do problema. Os testes ao performance e memória, tal como os anteriores, foram realizados pelo autor, sendo documentados e analisados posteriormente pelo orientador Eng. Hugo Trovão e/ou outros responsáveis da entidade acolhedora. 7.2.3 Testes de Integração com o CodeV O terceiro teste foi realizado ao longo da integração com o motor de análise de vulnerabilidades, ou seja, em dois momentos distintos do desenvolvimento. O primeiro após o parser suportar toda a linguagem nativa Java, altura da primeira integração com o motor de análise de vulnerabilidades. O segundo momento de testes foi após conclusão de todas as funcionalidades propostas terminadas, ou seja, após conclusão do parser. O presente teste consistiu na análise de vários projetos escolhidos por um responsável da entidade acolhedora que acompanhou todo o processo de integração. Foi atribuída a nota pass caso o motor de análise de vulnerabilidades reconhecesse com sucesso os nós da AST gerada (todos os já suportados pelo CodeV), estivessem corretamente preenchidos e a ordem dos mesmos na AST estivesse de acordo com o esperado pelo motor de análise de vulnerabilidades. Foram efetuados vários testes para validar cada integração, tendo de obter todos a nota pass para ser validada com sucesso. Caso, algum dos testes, obtivesse nota fail, o autor deveria proceder imediatamente à correção do parser, efetuando testes à funcionalidade que tinham causado o problema e, só depois, voltar a integrar o parser com o motor de vulnerabilidades. Estes testes foram realizados pelo autor em conjunto com o orientador Eng. Hugo Trovão e/ou outros responsáveis da entidade acolhedora, sendo o teste preenchido pelo Eng. Hugo Trovão, cabendo ao mesmo a validação da integração e do parser, visto ser o último teste a efetuar. A tabela 7.2 representa o template definido para os testes de integração que foram realizados. Foi preenchido com dados simulados para exemplificar um caso de teste. 47 Luís Laranjeira - PJMAS Tester: Luís Laranjeira ID Teste: 1 Data: 20/04/2013 Tipo de Teste: Teste de Integração. Compatibilidade com o CodeV: 90% Estimativa nós compatíveis: 80% Estimativa nós incompatíveis: 20% Observações: Os nós não compatíveis estão preenchidos incorretamente. Ações Efetuadas: Deve proceder-se à correção dos nós relativos à declaração de variáveis. Tabela 7.2: Exemplar de teste de integração. 7.3 Especificação do Ambiente e da Máquina de Testes Na tabela 7.3 estão apresentadas as especificações do ambiente de testes e da máquina utilizada para todos os testes efetuados ao longo do presente documento. Sistema Operativo Nome Arquitetura Processador Modelo Velocidade Número de Núcleos Número de Threads Intel® Smart Cache Memória Tipo Tamanho Total Tamanho Livre Velocidade Swap Tamanho Total Tamanho Livre Debian wheezy 64 Bits Intel(R) Core(TM) i3-2100 3,1 GHz 2 4 3 MB DDR3 4 GB ≈ 1 GB 1333 MHz 3 GB 3 GB Tabela 7.3: Especificações da máquina utilizada para testes 7.4 Resultados Obtidos No presente subcapítulo estão apresentados e analisados todos os resultados obtidos através dos testes realizados. Os testes propostos englobam testes às funcionalidades, testes ao parsing com projetos, testes à performance e memória utilizada pelo parser e por fim testes de integração com o motor de análise de vulnerabilidades. 48 Luís Laranjeira - PJMAS 7.4.1 Testes às Funcionalidades Na tabela 7.4 estão apresentados os resultados das validações das funcionalidades. Cada funcionalidade, tal como referido anteriormente, foi submetida a vários testes e foi validada apenas após passar com sucesso todos os testes. Funcionalidade Linguagem Java Comentários Packages e Imports Classes/Enum/Interface Variáveis/Objetos Funções Condições Iterações Try Catch Anotações e @Interface JSP Comentários Deteção HTML Scriptlet JSP e XML Declaration JSP e XML Expression JSP e XML Directive JSP e XML Standat Actions Alteração de Ciclos for Extensão de Anotações Extensão múltiplos exceptions nos catch Alteração nós da AST nas JSP Prioridade MUST MUST MUST MUST MUST MUST MUST MUST MUST HAVE HAVE HAVE HAVE HAVE HAVE HAVE HAVE HAVE MUST HAVE MUST HAVE MUST HAVE MUST HAVE MUST HAVE MUST HAVE MUST HAVE NICE TO HAVE NICE TO HAVE NICE TO HAVE NICE TO HAVE Pass X X X X X X X X X X X X X X X X X × X X Tabela 7.4: Resultado da Validação das Funcionalidades. Como é possível visualizar na mesma tabela, todas as funcionalidades implementadas pelo autor passaram nos respetivos testes com sucesso e foram assim validadas. A exceção é a extensão de Anotações, pelas razões já referidas anteriormente no capítulo 6.3. Todos os testes foram sujeitos a uma validação cuidada e rigorosa por parte do autor. Devido ao desenvolvimento ágil adotado, foram ainda efetuados testes que não foram documentados, pois o autor iria despender imenso tempo só em documentação, tempo esse vital para a implementação das funcionalidades em si. Estão presentes assim no anexo G.1 os testes finais de cada funcionalidade, confirmando o perfeito funcionamento dos requisitos. Os testes realizados englobaram código fonte feito pelo autor, código fonte de aplicações open source existentes na Internet e código fonte de soluções da entidade acolhedora para clientes. 7.4.2 Testes ao parsing com Projetos Na tabela 7.5 está um resumo de todos os projetos a que o parser desenvolvido foi sujeito. Tal como é possível verificar, o parser concluiu o parsing de todos os ficheiros de todos os projetos com sucesso, passando assim em todos os testes de parsing a que foi submetido. 49 Luís Laranjeira - PJMAS Total de Projetos Total ficheiros dos Projetos Total ficheiros Java Analisados 8 5354 4866 Parsing Concluído 5354 4866 Erro Parsing 0 0 Tabela 7.5: Resumo resultados parsing a projetos. Os projetos analisados demonstraram ser bastante importantes, pois foram detetados vários erros de parsing, os quais o autor corrigiu e voltou a efetuar a análise até obter resultados sem erros detetados. No anexo Testes às Funcionalidades, Parsing de Projetos estão apresentados os resultados finais aos projetos após correção de todos os erros, com mais detalhe sobre as analises. De realçar o projeto open source Eclipse JDK Core Component[5], que contém os ficheiros de código fonte definidos para teste do parser utilizado no próprio IDE da aplicação Eclipse, pois permitiu detetar vários erros no parser desenvolvido na presente dissertação/estágio. 7.4.3 Testes à Performance e Memória Parser Requisitos Definidos Resultados Obtidos Tempo médio (ms) 720 472.1 Memória média (MB) 40 17.89 Tabela 7.6: Resumo resultados obtidos ao performance e memória do parser. Após a realização dos testes relativos à performance e à memória foi construida a tabela 7.6, que representa a média dos valores obtidos nos testes realizados e os valores definidos como requisitos. As tabelas com os valores individuais de todos os testes efetuados estão presentes no anexo D. Como é possível verificar analisando a tabela, o parser desenvolvido respeita os dois requisitos não funcionais definidos, limite de tempo em que o parser deve efetuar o parsing do ficheiro de código fonte e memória máxima que pode utilizar para o mesmo, sendo os valores registados através dos testes, inferiores aos limites estipulados. Foram, portanto, validados os dois requisitos não funcionais mencionados. 7.4.4 Testes de Integração com o CodeV No anexo G.3 estão presentes os testes de integração efetuados. Na primeira fase de integração alguns dos nós PostfixExpression não estavam a ser preenchidos corretamente, tendo o autor procedido de imediato à correção do problema. Já a segunda fase de integração decorreu sem problemas, alguns nós da AST não foram reconhecidos pelo motor de análise de vulnerabilidades, algo que era esperado devido a serem novos nós implementados pelo autor. A integração foi efetuada pelo orientador Hugo Trovão em conjunto com o autor, tendo sido validada com sucesso por ambos. 50 Luís Laranjeira - PJMAS 7.5 Discussão dos Resultados Os resultados obtidos dos testes realizados foram bastante positivos, uma vez que todas as funcionalidades desenvolvidas foram validadas com sucesso. O parser, para além de suportar todas as tecnologias dos demais, possui a mais valia de suportar as JSP. Parser Eclipse JDT JavaParser JRefactory PMD PJMAS Tempo médio (ms) 1236.23 343.77 602.10 701.23 472.1 Memória média (MB) 66.59 14.28 42.57 36.83 17.89 Tabela 7.7: Comparação com outros Parsers analisados. Em termos de performance e memória, como se pode verificar analisando a tabela 7.7, os resultados foram igualmente bons. Apenas o parser JavaParser demorou menos tempo e ocupou menos memória a analisar o ficheiro de teste utilizado para a comparação, no entanto, não suporta nem o JDK 1.7 nem a sintaxe das JSP. Por fim, a integração foi concluída com sucesso e o CodeV já analisa código fonte Java. 51 Capítulo 8 Conclusão O presente capítulo apresenta uma reflexão do autor sobre a sua dissertação, algumas reflexões sobre o desenrolar dos trabalhos e uma breve análise ao futuro da ferramenta implementada. 8.1 Conclusão da Dissertação Este documento representa o empenho, esforço e dedicação do autor ao longo do presente ano letivo, apresentado de forma clara e objetiva de todo o processo de construção da aplicação. Os “caminhos” nem sempre são fáceis e este projeto não fugiu à regra. Mas a motivação e a alegria de ter chegado ao fim, de ter superado todas as etapas e com a certeza de dever cumprido é muito gratificante. Este projeto teve o seu início com a análise de ferramentas, com funcionalidades similares e com a escolha sobre o melhor caminho a seguir. De um lado a criação de um parser novo, do outro o aproveitamento de um parser existente. Após selecionada a primeira opção foram analisadas ferramentas para a construção da solução encontrada. De seguida teve lugar a implementação da solução definida, acompanhada por testes iterativos a todos os requisitos. Concluída esta fase foram efetuados vários testes rigorosos à aplicação tendo como finalidade a verificação do cumprimento de todos os requisitos definidos. Esta foi uma tarefa deveras importante, não só porque foi a forma do autor provar que conseguiu atingir os objetivos a que se propôs mas, também, porque existe uma terceira entidade envolvida para além do autor e da Universidade de Coimbra, a Dognædis. A Dognædis disponibilizou todas as condições necessárias para que o autor conseguisse construir a solução. É importante referir que a ferramenta desenvolvida vai, igualmente, de encontro às pretensões da entidade acolhedora. Analisados os resultados obtidos nas validações aos requisitos, o autor conclui que atingiu, claramente, os objetivos a que se propôs: criar uma solução que possibilitasse ao CodeV aumentar a segurança nas aplicações JavaEE/J2EE. 52 Luís Laranjeira - PJMAS 8.2 Reflexões Sobre o Desenrolar dos Trabalhos O projeto PJMAS foi, pois, concluído com sucesso, uma vez que todos os objetivos definidos foram alcançados. Todas as funcionalidades propostas foram desenvolvidas e validadas com objetividade e clareza, à exceção da extensão de anotações, devido aos problemas descritos no capítulo 6.3. De uma forma global os trabalhos desenrolaram-se num bom ritmo, apesar de algumas contrariedades encontradas, o autor conseguiu superá-las, encontrando soluções adequadas e atingindo os objetivos esperados. O planeamento efetuado teve extrema importância, pois através do mesmo o autor conseguiu situar-se no tempo, verificando se estava a desviar-se dos objetivos intercalares, “obrigandoo” a terminar as micro tarefas o mais rápido possível. Neste processo, muito contribuíram as iterações de acompanhamento realizadas ao longo do primeiro semestre, pois permitiram ao autor perceber qual a margem de erro com que estimava as suas tarefas. 8.3 Futuro da Aplicação O futuro da aplicação está agora nas mãos da Dognædis. Como ficou provado, a aplicação é funcional e cumpre os objetivos propostos. O autor identificou os seguintes trabalhos futuros: • Implementação de um método que ao detetar erros de parsing, continue a gerar a AST, permitindo que, caso o ficheiro de código fonte contenha erros de sintaxe, seja analisado na mesma todo o restante conteúdo. • Expansão do parser para análise a JavaServer Faces (JSF). JSF é uma framework ModelView-Controller (MVC) em Java, para construção de aplicações web de forma ágil. • Manutenção e implementação de atualizações que possam ser lançadas ao JDK. Embora o parser, no presente, seja parte integrante de uma aplicação (CodeV), é um módulo independente e que pode, no futuro, pode facilmente ser incorporado noutra aplicação que necessite de tais funcionalidades. 53 Bibliografia [1] “Dogædis CodeV.” https://codev.dognaedis.com. Acedido a 18 Outubro de 2012. [2] “JavaEE.” http://docs.oracle.com/javaee/. Acedido a 22 Novembro de 2012. [3] “Dogædis Press.” https://www.dognaedis.com/press/. Acedido a 18 Outubro de 2012. [4] M. Vieira, “Msd - bottom-up estimation - a real process,” tech. rep., October 2010. [5] “Eclipse JDT.” http://www.eclipse.org/jdt/. Acedido a 16 de Fevereiro de 2013. [6] “Eclipse JDT Core Component.” http://www.eclipse.org/jdt/core/index.php. Acedido a 17 de Fevereiro de 2013. [7] “JRefactory.” http://jrefactory.sourceforge.net/. Acedido a 17 de Fevereiro de 2013. [8] “Apache License, Version 2.0.” http://www.apache.org/licenses/LICENSE-2.0. Acedido a 17 de Fevereiro de 2013. [9] “JavaParser.” http://code.google.com/p/javaparser/. Acedido a 17 de Fevereiro de 2013. [10] “Licença GNU Lesser GPL.” http://www.gnu.org/licenses/lgpl.html. Acedido a 17 de Fevereiro de 2013. [11] “PMD Website.” http://pmd.sourceforge.net. Acedido a 17 de Fevereiro de 2013. [12] “Documentation of JSP support in PMD.” http://pmd.sourceforge.net/pmd-5.0.4/jspsupport. html. Acedido a 17 de Fevereiro de 2013. [13] “Licença BSD.” http://directory.fsf.org/wiki/License:BSD_3Clause. Acedido a 29 Dezembro de 2012. [14] “Alterações sintáticas no JDK 1.7.” https://blogs.oracle.com/darcy/entry/project_coin_ final_five. Acedido a 18 de Fevereiro de 2013. [15] “Alterações nas exceções no JDK 1.7.” http://www.oracle.com/technetwork/articles/java/ java7exceptions-486908.html. Acedido a 18 de Fevereiro de 2013. [16] “VisualVM.” http://visualvm.java.net/. Acedido a 18 de Fevereiro de 2013. [17] “YACC.” http://dinosaur.compilertools.net/. Acedido a 16 Janeiro de 2013. [18] “Bison.” http://www.gnu.org/software/bison/. Acedido a 16 Janeiro de 2013. [19] “Licença GNU GPL v3.” http://www.gnu.org/licenses/gpl.html. Acedido a 29 Dezembro de 2012. [20] “JavaCC.” http://javacc.java.net. Acedido a 22 Novembro de 2012. 54 Luís Laranjeira - PJMAS [21] R. E. Pattis, “Ebnf: A notation to describe syntax,” [22] “ANTLR.” http://www.antlr.org. Acedido a 22 Novembro de 2012. [23] “Gold.” http://goldparser.org/. Acedido a 27 Novembro de 2012. [24] “Licença Zlib.” http://directory.fsf.org/wiki/License:Zlib. Acedido a 29 Dezembro de 2012. [25] J. Gosling, B. Joy, G. Steele, G. Bracha, and A. Buckley, The Java Language Specefication - Java SE 7 Edition. 500 Oracle Parkway M/S 5op7, California 94065, U.S.A.: Oracle America, Inc, July 2012. [26] P. Delisle, J. Luehe, and M. Roth, JavaServer PagesSpecification - Version 2.1. 4150 Network Circle, Santa Clara, California 95054, U.S.A: SUN MICROSYSTEMS, INC., May 2006. [27] T. Copeland, Generating Parsers With JavaCC. Alexandria: Centennial Books, 2009. [28] “Checkmarx.” http://www.checkmarx.com/. Acedido a 22 Novembro de 2012. [29] “CodeSecure.” http://www.armorize.com/codesecure/index.php. Acedido a 22 Novembro de 2012. [30] “IBM Security AppScan Source.” http://www-01.ibm.com/software/rational/products/ appscan/source/. Acedido a 22 Novembro de 2012. [31] “OWASP, The Open Web Application Security Project.” https://www.owasp.org/index.php/Main_ Page. Acedido a 29 Dezembro de 2012. [32] “SANS.” http://www.sans.org/. Acedido a 29 Dezembro de 2012. [33] “Veracode: Static Analysis Tool.” http://www.veracode.com/security/static-analysis-tool. Acedido a 29 Dezembro de 2012. [34] “BNF and EBNF: What are they and how do they work?.” http://www.garshol.priv.no/download/ text/bnf.html. Acedido a 14 Novembro de 2012. [35] “Eclipse Public License - v 1.0.” http://www.eclipse.org/legal/epl-v10.html. Acedido a 17 de Fevereiro de 2013. [36] “Nymble, Open Source CMS coded in JSP.” http://cis-linux2.temple.edu:8080/SP11_2308_ tuc22289/. Acedido a 27 Maio de 2013. [37] “Java2EE Samples, página com vários samples para download.” http://www.oracle.com/ technetwork/java/javaee/downloads/java-archive-downloads-eesdk-419427.html. Acedido a 27 Maio de 2013. [38] “airline reservation project.” http://1000projects.org/airline-reservation-system. -jsp-project-source-code.html. Acedido a 27 Maio de 2013. [39] “Website visitor analyzer project.” http://techspalace.blogspot.pt/2013/01/ jsp-and-java-project-for-it-students.html. Acedido a 27 Maio de 2013. [40] A. J. D. Reis, Compiler Construction Using Java, JavaCC, and Yacc. Hoboken, New Jersey: WILEY, John Wiley & Sons, Inc., 2012. [41] S. Kottwitz, LATEX - Beginner’s Guide. Birmingham, B27 6PA, UK.: PACKT Publishing, Março 2011. 55 Parte I Apêndices 56 Apêndice A Diagrama de Gantt i A.1 02/10/12 14:00 2.3) Documentação 26/10/12 14:00 01/11/12 14:00 3.3) Análise de Ferramentas concorrentes ao CodeV 3.4) Documentação ii 25/12/12 14:00 5.4) Documentação 25/01/13 18:00 03/01/13 18:00 01/01/13 18:00 03/01/13 18:00 26/12/12 18:00 21/12/12 18:00 13/12/12 18:00 05/12/12 18:00 26/12/12 18:00 13d 2d 3d 5d 2d 5d 5d 6d 18d 2d 1d 4d 2d 3d 12d 2d 3d 5d 8d 18d 2d 2d 2d 6d 4d Effort Set 2012 Out 2012 Nov 2012 Figura A.1: Diagrama de Gantt referente às tarefas do primeiro semestre. 04/01/13 14:00 02/01/13 14:00 6.2) Diagrama de Gantt 2º semestre 7) Documentação 27/12/12 14:00 6.1) WBS 2º semestre 27/12/12 14:00 14/12/12 14:00 5.3) Especificação do Parser 6) Planeamento das Atividades e Calendarização 2º semestre 06/12/12 14:00 27/11/12 14:00 5) Definição da Aplicação 27/11/12 14:00 22/11/12 14:00 4.5) Documentação 5.2) Arquitetura do Sistema 21/11/12 18:00 21/11/12 14:00 4.4) Análise de Riscos 5.1) Estudo da Árvore 20/11/12 18:00 4.3) Estudo da integração com a plataforma de análise 14/11/12 14:00 Vulnerabilidades 23/11/12 18:00 13/11/12 18:00 09/11/12 14:00 08/11/12 18:00 06/11/12 14:00 4.2) Requisitos não Funcionais 23/11/12 18:00 02/11/12 18:00 31/10/12 18:00 25/10/12 18:00 17/10/12 18:00 02/11/12 18:00 03/10/12 18:00 28/09/12 18:00 26/09/12 18:00 03/10/12 18:00 21/09/12 18:00 End Ago 2012 4.1) Requisitos Funcionais 06/11/12 14:00 18/10/12 14:00 3.2) Comparação dos Geradores de Parsers existentes 4) Análise de Requisitos e Integração na Plataforma 04/10/12 14:00 3.1) Estudo Geradores de Parsers Existentes 04/10/12 14:00 27/09/12 14:00 3) Estado da Arte 25/09/12 14:00 2.2) WBS 1º semestre 25/09/12 14:00 2) Planeamento das Atividades e Calendarização 1º semestre 2.1) Diagrama de Gantt 1º semestre 18/09/12 14:00 Start 1) Ambientação à Empresa Title Diagrama de Gantt do Primeiro Semestre Dez 2012 Jan 2013 Fev 2013 Luís Laranjeira - PJMAS iii 04/06/13 18:00 27/05/13 09:00 13/06/13 09:00 11) Escrita de Relatório Final 28/06/13 18:00 12/06/13 18:00 12d 6d 7d 2d 1d 3d 6d 5d 5d 7d 8d 8d 7d 8d 43d 5d 5d 5d 4d 1d 1d Fev 2013 Mar 2013 Abr 2013 Mai 2013 Figura A.2: Diagrama de Gantt referente às tarefas do segundo semestre (plano inicial). 05/06/13 09:00 10) Conclusões e Possíveis Alterações 9) Integração no CodeV 24/05/13 18:00 23/05/13 09:00 8.3) Verificação 3: Todos os nós estão bem preenchidos 22/05/13 18:00 22/05/13 09:00 8.2) Verificação 2: Respeita requisitos nãofuncionais 21/05/13 18:00 17/05/13 09:00 24/05/13 18:00 16/05/13 18:00 09/05/13 18:00 02/05/13 18:00 23/04/13 18:00 11/04/13 18:00 01/04/13 18:00 21/03/13 18:00 09/05/13 18:00 11/03/13 18:00 04/03/13 18:00 25/02/13 18:00 18/02/13 18:00 12/02/13 18:00 11/02/13 18:00 2d Jan 2013Effort 12/02/13 18:00 End 8.1) Verificação 1: "Parsing" de todo o ficheiro 17/05/13 09:00 8) Testes finais ao parser 03/05/13 09:00 6.6) Try Catch 10/05/13 09:00 24/04/13 09:00 6.5) Classes 7) Deteção de Anotações 12/04/13 09:00 6.4) Iterações 12/03/13 09:00 6) Deteção da linguagem comum Java 02/04/13 09:00 05/03/13 09:00 5) Deteção de Importes 6.3) Condições 26/02/13 09:00 4) Deteção de Código HTML 22/03/13 09:00 19/02/13 09:00 3) Deteção de Comentários 12/03/13 09:00 13/02/13 09:00 2) Instalação, configuração e ambientação às ferramentas necessárias 6.2) Funções 12/02/13 09:00 1.2) Alteração dos aspetos considerados importantes para o desenrolar do estágio 6.1) Variáveis/Objetos 11/02/13 09:00 11/02/13 09:00 Start 1.1) Análise de Conselhos/Criticas proferidos pelo Júri na Defesa Intermédia 1) Discussão sobre Defesa Intermédia Title A.2 Diagrama de Gantt do Segundo Semestre (Plano Inicial) Jun 2013 Jul 2013 Luís Laranjeira - PJMAS A.3 11/04/13 18:00 16/04/13 18:00 06/05/13 18:00 10/05/13 18:00 21/02/13 09:00 28/02/13 09:00 07/03/13 09:00 11/03/13 09:00 12/04/13 09:00 17/04/13 09:00 07/05/13 09:00 13/05/13 09:00 17/05/13 09:00 23/05/13 09:00 11/03/13 09:00 27/05/13 09:00 03/06/13 09:00 06/06/13 09:00 3) Comparação entre criar novo parser ou alterar um existente 4) Especificação completa da Gramática do Parser 5) Instalação, configuração e ambientação às ferramentas necessárias 6) Deteção da linguagem comum Java 7) Integração no CodeV 1ª fase 8) JSP e Expressões XML nos JSP 9) Extensão de Ciclos for 10) Extensão de Anotações 11) Alteração nós da AST nas JSP 12) Extensão múltiplos exceptions nos Catch 13) Testes iterativos 14) Testes finais ao parser 15) Integração no CodeV 2ª fase 16) Escrita de Relatório Final 17d 3d 5d 55d 2d 4d 4d 4d 14d 3d 24d 2d 5d 5d 6d Fev 2013 Mar 2013 Abr 2013 Figura A.3: Diagrama de Gantt referente às tarefas do segundo semestre. 28/06/13 18:00 05/06/13 18:00 31/05/13 18:00 24/05/13 18:00 24/05/13 18:00 22/05/13 18:00 16/05/13 18:00 08/03/13 18:00 06/03/13 18:00 27/02/13 18:00 20/02/13 18:00 13/02/13 09:00 2) Adições ao Estado da Arte 2d Jan 2013 Effort 12/02/13 18:00 End 11/02/13 09:00 Start 1) Discussão sobre Defesa Intermédia Title Diagrama de Gantt do Segundo Semestre Mai 2013 Jun 2013 Jul 2013 Luís Laranjeira - PJMAS iv Apêndice B Work Breakdown Structure v Luís Laranjeira - PJMAS B.1 WBS Referente ao Primeiro Semestre Figura B.1: WBS referente às tarefas do primeiro semestre. vi Luís Laranjeira - PJMAS B.2 WBS Referente ao Segundo Semestre Figura B.2: WBS referente às tarefas do segundo semestre. vii Apêndice C Estimação de Tarefas, Segundo Semestre viii Luís Laranjeira - PJMAS Tarefa Discussão sobre defesa intermédia Adições ao Estado da Arte Comparação entre criar novo parser e aproveitar exitente Especificação completa da gramática do parser Instalação e ambientação às ferramentas Java – Reserved Tokens e Comentários Java – Packages e Imports Java – Class, Enum e Interface Java – Variáveis/Objetos e operações Java – Funções e Construtores Java – Condições Java – Iterações Java – Try Catch Java – Anotações e @Interface Integração com o CodeV - 1ª Fase JSP – Reserved Tokens e Comentários JSP – Deteção HTML JSP – Scriptlet JSP e XML JSP – Expression JSP e XML JSP – Directive JSP e XML JSP – Standart Actions Alteração de Ciclos for na AST Extensão de Anotações na AST Alteração nós das AST nas JSP Extensão múltiplos exceptions nos catch Integração com o CodeV – 2ª Fase Testes Finais ao Parser e Documentação Relatório MC 1 5 4 3 1 1 1.5 4 3 1.5 1.5 1.5 1.5 3 2 1 1 1.5 0.5 3 4 3 3 3 1 2 3 15 CN 2 6 5 5 2 1 2 5 4 2 2 2 2 4 3 1 1 2 1 4 5 4 4 4 2 3 5 17 PC 3 8 7 7 2 1 2.5 6 5 2.5 3 3 3 5 4 1 1 3 1.5 6 6 5 8 6 4 5 10 20 CE 2.00 6.17 5.17 5.00 1.83 1.00 2.00 5.00 4.00 2.00 2.08 2.08 2.08 4.00 3.00 1.00 1.00 2.08 1.00 4.17 5.00 4.00 4.50 4.17 2.17 3.17 5.50 17.17 Tabela C.1: Tabela do esforço de cada tarefa do PJMAS, 2º Semestre. Legenda: MC- Melhor Caso, CN - Caso Normal, PC - Pior Caso, CE- Caso Expectado. Tarefa Total Melhor Caso* 88,53 *2% Confiança Caso Normal 100 Pior Caso** 116,13 **98% Confiança Caso Expectado 102,33 Tabela C.2: Tabela do esforço geral do PJMAS, 2º semestre. Tarefa Total Melhor Caso 75.5 Pior Caso 138,5 Caso Expectado 102,33 Soma Individual 47,62 Tabela C.3: Tabela auxiliar no cálculo do esforço. ix Desvio Padrão 6,90 Luís Laranjeira - PJMAS Percentagem de Confiança 2% 10% 16% 20% 25% 30% 40% 50% 60% 70% 75% 80% 84% 90% 98% Cálculo 88.53 93.50 95.43 96.54 97.71 98.74 100.61 102.33 104.06 105.92 106.96 108.13 109.23 111.17 116.13 Tabela C.4: Variação do tempo estimado conforme a percentagem de confiança. x Apêndice D Testes Performance e Memória xi Luís Laranjeira - PJMAS Teste 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 Média DP Eclipse JDT 1175 1049 1058 1242 1383 1045 1266 1436 1148 1102 1587 1170 1315 1415 1324 1057 1303 1101 1316 1237 1168 1322 1210 1326 1314 1229 1237 1244 1209 1099 1236.23 128.16 Tempo de Execução (ms) JavaParser JRefactory PMD 294 618 822 352 676 733 361 618 617 352 628 716 354 543 730 357 628 728 326 564 692 356 600 744 356 620 613 354 608 720 361 620 614 320 544 645 356 602 741 305 590 721 351 566 747 328 570 620 297 619 738 351 617 722 356 624 720 354 542 707 302 580 676 361 623 712 357 578 701 368 609 618 366 621 698 358 621 633 318 697 707 358 570 731 357 541 738 327 626 733 343.77 602.10 701.23 22.004 37.14 50.42 PJMAS 435 479 413 450 495 449 448 480 499 469 417 462 454 480 493 474 458 547 461 437 481 416 479 514 473 477 555 523 464 481 472.1 34.06 PJMAS(1) 720 821 990 619 754 764 780 727 781 772 745 780 628 731 771 761 774 593 774 666 792 722 641 613 611 742 685 742 696 758 731.77 79.49 Tabela D.1: Tempo de execução para cada teste, com ficheiro de 11080 linhas de código. Legenda: 1 - Versão antes da otimização. DP - Desvio Padrão. xii Luís Laranjeira - PJMAS Teste 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 Média MBytes DP Eclipse JDT 69999144 68486512 71463144 75709632 70725480 70056136 70793280 69449936 71040800 71243600 69633936 74323848 70549240 71021128 53697504 74144400 72146792 51873536 70494288 71163456 70398792 71213872 70246424 71842192 73239152 70903752 71998416 67875040 70373072 68610104 69823886.93 66.59 4930779 JavaParser 15175216 13882672 15812448 15174688 14201776 14519928 15811920 14201776 13882672 13516752 12879520 14201664 15812472 15175216 14989488 15626576 14989472 15626584 15925248 14989128 15308088 15308080 15626744 14989040 14989488 15626584 14989520 14989392 14989424 15925248 14971227.47 14.28 762379.2 Memória Utilizada (Bytes) JRefactory PMD 45391096 39470568 43471608 39444952 45391096 38203920 44770280 38186928 44116856 38187600 45399144 38195184 46028448 39453912 45374568 39461392 44109656 39461672 46003736 37549800 46012064 38195344 43471560 38212120 45382744 38165784 45391080 39486488 44088264 39444864 45358216 38195032 45399288 37541656 45382904 39470160 43487928 39461328 42201368 38196592 43536320 38203672 44116872 38178880 44108504 38195648 45382936 38172120 46003576 38211976 45366616 38187632 43479720 38171736 43467608 38195672 42568288 39469944 44762064 39461856 44634146.93 38614481.07 42.57 36.83 1071502 675684.8 PJMAS 18300576 18308208 18611792 18618496 18618464 18619648 19249120 19255784 18611096 19255960 18610296 19263824 18618464 19256768 19247752 18618592 18610536 18937248 18610568 19256568 18300168 18300144 18618952 18618576 18619760 18635064 18619872 19255792 19272120 17981080 18756709.6 17.89 371664.9 PJMAS(1) 18764032 19161808 19099312 19744800 19753152 19434208 20398200 20062768 19768688 19756320 20067160 20071040 19744104 19715168 20381792 20708712 20087704 20079520 19722344 20716832 19425904 19744528 20064512 19752792 20724984 20071400 19698256 19752728 19433800 20103736 19867010.13 18.95 459232 Tabela D.2: Memória utilizada em cada teste, com ficheiro de 11080 linhas de código. Legenda: 1 - Versão antes da otimização. DP - Desvio Padrão. xiii Apêndice E Aplicações Concorrentes ao CodeV E.1 Veracode: Static Analysis Tool Desenvolvida pela empresa Veracode[33], esta é uma ferramenta de análise estática, uma ferramenta interessante visto detetar as vulnerabilidades das aplicações sem ser necessário, nem o código fonte nem que a aplicação esteja a correr. O facto de não ser necessário o código fonte, analisando antes o código binário(compilado), é uma enorme vantagem para o utilizador, visto ser bastante improvável conseguir obter o código fonte quando é adquirido software (gratuito ou pago) de terceiros. A aplicação assenta num Software-as-a-Service (SaaS), onde o cliente submete o seu binário numa plataforma online, recebendo o resultado em 24 horas. Sendo as vulnerabilidades detetadas por esta aplicação XSS, Directory traversal, SQL injection, Code injection, entre outras, abrangendo um vasto número de linguagens, entre elas C/C++, C# e Java. E.2 CodeSecure Aplicação desenvolvida pela Armorize, empresa dedicada à área de segurança web. O CodeSecure[29] é uma plataforma que analisa código fonte e identifica vulnerabilidades em aplicações web, produzindo relatórios onde fornece soluções para os problemas encontrados, sendo esta também uma ferramenta de gestão centralizada de vulnerabilidades. Para a análise ao código fonte é possível submeter o código fonte comprimido num arquivo ZIP, ou submeter ficheiros remotamente por via de Subversion, FTP ou Microsoft Windows share. É uma aplicação criada para analisar vulnerabilidades em aplicações web, suportando as linguagens ASP.NET, VB.NET, C#, Java/J2EE, JSP, EJB, PHP, Classic ASP e VBScript. Permite agendamento de verificações do código, bem como controlo de versões de teste efetuadas. Tal como o CodeV é uma aplicação que, ao que tudo indica, fará a sua análise utilizando parsers e AST, isto porque o mesmo motor, é capaz de analisar várias linguagens de programação diferentes. E.3 Checkmarx Static code analysis Criada e desenvolvida pela Checkmarx[28], empresa que proporciona soluções para encontrar e contornar problemas derivados de vulnerabilidades que o código possa criar na aplicação, é uma ferramenta bastante completa. Tal como no CodeSecureE.2, é possível submeter o código xiv Luís Laranjeira - PJMAS na interface web da aplicação, com todo o código fonte dentro de um ficheiro ZIP. Permite configurar agendamentos para a próxima execução, escolher os testes que se pretende efetuar ao código e visualizar as versões que foram submetidas, tal como o seu relatório. Por cada teste é gerado um relatório com todas as vulnerabilidades encontradas, bem como o grau de cada uma (quanto mais alto o valor, pior é a vulnerabilidade), podendo descarregar o relatório em qualquer altura em vários formatos a partir da área pessoal no website. A aplicação deteta um enorme número de vulnerabilidades, dando principal ênfase ao top 10 do The Open Web Application Security Project (OWASP) e aos 25 “SANS standards out of the box” (25 erros de software mais perigosos), estando bem documentadas no próprio relatório, quer com a explicação, quer com exemplos de como pode ser usada a vulnerabilidade, tendo ainda possibilidade de visualizar o local exato das mesmas no código a partir do website da aplicação. Neste momento suporta um vasto leque de linguagens de programação, sendo elas Java, C# / .NET, PHP, C, C++, Visual Basic 6.0, VB.NET, Flash, APEX, Ruby, Javascript, ASP, Perl, Android e Objective C. Tal como o autor assinalou na aplicação anterior, esta também pressupõe que use parsers e AST para analisar o código, sendo de seguida um motor único para todas as linguagens que pesquisa as vastas vulnerabilidades que possam existir. De facto é um funcionamento poderosíssimo, podendo assim em qualquer momento ser adicionada uma linguagem nova à aplicação. É possível verificar no website da empresa que têm mais produtos capazes de interagir com o Static code anelysis, e capazes de aumentar a simplicidade de processos e potencializar uma correção mais fácil e rápida das vulnerabilidades, como por exemplo plugin de interação com o eclipse. E.4 IBM Security AppScan Source Esta aplicação da IBM[30] permite a deteção de vulnerabilidades em aplicações, através da análise de código fonte. Permite a integração com IDEs o que facilita o trabalho conjunto entre equipas de desenvolvimento e as de segurança, fornecendo a ambas a informação necessária. Entre outras, esta aplicação segue as boas práticas de desenvolvimento WEB, como é o caso do OWASP Top 10. As linguagens de desenvolvimento analisadas são, entre outras, C, C++, .NET, PHP e Cobol. A solução da IBM passa pela instalação de um servidor de gestão central de vulnerabilidades, comunicando estas quer com os plugins nos IDEs, quer com a aplicação que existe para ambiente Windows. xv Apêndice F Gramática do Parser <HTML_STATE , DEFAULT> TOKEN : { <JSP_SCRIPTLET_XML : "< j s p : s c r i p t l e t >"> : JSP_JAVA | <JSP_DECLARATION_XML : "< j s p : d e c l a r a t i o n >"> : JSP_JAVA | <JSP_EXPRESSION_XML : "< j s p : e x p r e s s i o n >"> : JSP_JAVA | <JSP_DIRECTIVE_XML : "< j s p : d i r e c t i v e . " > : JSP_STATE | <JSP_JSPTAG_BEGIN : "< j s p : " > : JSP_STATE | <JSP_BEGIN : "<%"> : JSP_JAVA | <JSP_DIRECTIVE : "<%@"> : JSP_STATE | <JSP_DECLARATION : " <%!" > : JSP_JAVA | <JSP_COMMENT_BEGIN : "<%−−"> : JSP_COMMENT } / ∗ white spaces and Comments ∗ / <JSP_IMPORT_STATE> SKIP : { " " | "\ t " | "\n " | "\ r " } <JSP_JAVA> SKIP : { " " | "\ t " | "\n " | "\ r " | < " / / " ( ~ [ " \ n " , " \ r " , " % " ] | " % " ~ [ " > " ] ) ∗ ( " \ n " | " \ r " | " \ r \n " ) ?> | <"/∗" ( ~ [ " ∗ " ] ) ∗ " ∗ " ( " ∗ " | ~ [ " ∗ " , " / " ] ( ~ [ " ∗ " ] ) ∗ " ∗ " ) ∗ "/" > } <DEFAULT> SKIP : { " " | "\ t " | "\n " | "\ r " | < " / / " ( ~ [ " \ n " , " \ r " ] ) ∗ ( " \ n " | " \ r " | " \ r \n " ) ?> | <"/∗" ( ~ [ " ∗ " ] ) ∗ " ∗ " ( " ∗ " | ~ [ " ∗ " , " / " ] ( ~ [ " ∗ " ] ) ∗ " ∗ " ) ∗ "/" > } <JSP_STATE> SKIP : { " " | "\ t " | "\n " | "\ r " xvi Luís Laranjeira - PJMAS | < " / / " ( ~ [ " \ n " , " \ r " ] ) ∗ ( " \ n " | " \ r " | " \ r \n " ) > } <HTML_STATE> TOKEN [ IGNORE_CASE ] : { <JSP_DIRECTIVE_XML_CLOSE : " </ j s p : d i r e c t i v e . " > : JSP_STATE | <JSP_JSPTAG_CLOSE_BEGIN : " </ j s p : " > : JSP_STATE | <HTML_OTHER : " < " ~ [ " % " ] > | <HTML : ( ~ [ " < " ] | " < " ~ [ " % " , " j " , " / " ] ) +> } <HTML_STATE , RTATTRIBUTE_STATE , DEFAULT> TOKEN : { <JSP_EXPR : "<%="> : JSP_JAVA } <RTATTRIBUTE_STATE> TOKEN : { <CONSTANT : ( ~ [ " < " , " \ " " , " \ ’ " ] | " < " ~ [ " % " ] ) +> } <JSP_IMPORT_STATE , RTATTRIBUTE_STATE> TOKEN : { <JSP_QUOTE : " \ " " > | <JSP_PELICA : " \ ’ " > } <JSP_IMPORT_STATE> TOKEN : { <JSP_COMMA : " , " > | <JSP_IMPORT_TEXT : ( ~ [ " \ " " , " , " , " } " , " \ ’ " ] ) +> <JSP_COMMENT> SKIP : { <~[]> } <JSP_COMMENT> TOKEN : { <JSP_COMMENT_END : "−−%>"> : HTML_STATE } <JSP_STATE> TOKEN [ IGNORE_CASE ] : { <JSP_STATE_END : "%>"> : HTML_STATE | <JSP_JSPTAG_END : "/ >" > : HTML_STATE | <JSP_JSPTAG_CLOSE : " >" > : HTML_STATE | <JSP_INCLUDE : " i n c l u d e "> | <JSP_TAG : " tag "> | <JSP_TAGLIB : " t a g l i b "> | <JSP_PAGE : " page"> | <JSP_VARIABLE : " v a r i a b l e "> | <JSP_ATTRIBUTE : " a t t r i b u t e "> | <JSP_PARAM : " param"> | <JSP_PARAMS : " params "> | <JSP_LANGUAGE : " language "> | <JSP_EXTENDS : " e x t e n d s "> | <JSP_IMPORT : " i m p o r t "> | <JSP_SESSION : " s e s s i o n "> | <JSP_BUFFER : " b u f f e r "> | <JSP_AUTOFLUSH : " a uto Flu sh "> | <JSP_ISTHREADSAFE : " i s T h r e a d S a f e "> | <JSP_INFO : " i n f o "> | <JSP_ERRORPAGE : " errorPage "> | <JSP_ISERRORPAGE : " i s E r r o r P a g e "> | <JSP_CONTENTTYPE : " contentType "> | <JSP_PAGEENCODING : " pageEncoding "> | <JSP_ISELIGNORED : " i s E L I g n o r e d "> | <JSP_URI : " u r i "> xvii Luís Laranjeira - PJMAS | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | } <JSP_PREFIX : " p r e f i x "> <JSP_TAGDIR : " t a g d i r "> <JSP_DISPLAY_NAME : " d i s p l a y −name"> <JSP_BODY_CONTENT : " body−c o n t e n t "> <JSP_DYNAMIC_ATTRIBUTES : " dynamic−a t t r i b u t e s "> <JSP_SMALL_ICON : " small−i c o n "> <JSP_LARGE_ICON : " l a r g e−i c o n "> <JSP_DESCRIPTION : " d e s c r i p t i o n "> <JSP_EXAMPLE : " example "> <JSP_ASSIGN : "=" > <JSP_TRUE : " t r u e "> <JSP_FALSE : " f a l s e "> <JSP_NULL : " n u l l "> <JSP_FILE : " f i l e "> <JSP_NAME : " name"> <JSP_ID : " i d "> <JSP_CLASS : " c l a s s "> <JSP_REQUIRED : " r e q u i r e d "> <JSP_FRAGMENT : " f r a g m e n t "> <JSP_RTEXPRVALUE : " r t e x p r v a l u e "> <JSP_TYPE : " type "> <JSP_NAME_GIVEN : " name−g i v e n "> <JSP_VARIABLE_CLASS : " v a r i a b l e −c l a s s "> <JSP_SCOPE : " scope "> <JSP_DECLARE : " d e c l a r e "> <JSP_NAME_FROM_ATTRIBUTE : " name−from−a t t r i b u t e "> <JSP_ALIAS : " a l i a s "> <JSP_USE_BEAN : " useBean"> <JSP_SET_PROPERTY : " s e t P r o p e r t y "> <JSP_GET_PROPERTY : " g e t P r o p e r t y "> <JSP_FORWARD : " f o r w a r d "> <JSP_PLUGIN : " p l u g i n "> <JSP_INVOKE : " i n v o k e "> <JSP_DO_BODY : " doBody"> <JSP_ELEMENT : " element "> <JSP_OUTPUT : " o u t p u t "> <JSP_PROPERTY : " p r o p e r t y "> <JSP_VALUE : " v a l u e "> <JSP_COLON : " : " > <JSP_JAVA> TOKEN : { <JSP_END : "%>"> : HTML_STATE | <JSP_DECLARATION_XML_END : " </ j s p : d e c l a r a t i o n >"> : HTML_STATE | <JSP_EXPRESSION_XML_END : " </ j s p : e x p r e s s i o n >"> : HTML_STATE | <JSP_SCRIPTLET_XML_END : " </ j s p : s c r i p t l e t >"> : HTML_STATE } <DEFAULT , JSP_JAVA> TOKEN : { <ABSTRACT : " a b s t r a c t "> | <ASSERT : " a s s e r t "> | <BOOLEAN : " boolean "> | <BREAK : " break "> | <BYTE : " byte "> | <CASE : " case "> | <CATCH : " c a t c h "> | <CHAR : " char "> | <CLASS : " c l a s s "> | <CONST : " c o n s t "> | <CONTINUE : " c o n t i n u e "> | <_DEFAULT : " d e f a u l t "> | <DO: " do"> xviii Luís Laranjeira - PJMAS | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | } <DOUBLE : " double "> <ELSE : " e l s e "> <ENUM: " enum"> <EXTENDS : " e x t e n d s "> <FALSE : " f a l s e "> <FINAL : " f i n a l "> <FINALLY : " f i n a l l y "> <FLOAT : " f l o a t "> <FOR : " f o r "> <GOTO: " goto "> <IF : " i f "> <IMPLEMENTS : " implements "> <IMPORT : " i m p o r t "> <INSTANCEOF : " i n s t a n c e o f "> <INT : " i n t "> <INTERFACE : " i n t e r f a c e "> <LONG: " long "> <NATIVE : " n a t i v e "> <NEW: " new"> <NULL : " n u l l "> <PACKAGE : " package "> <PRIVATE : " p r i v a t e "> <PROTECTED : " p r o t e c t e d "> <PUBLIC : " p u b l i c "> <RETURN : " r e t u r n "> <SHORT : " s h o r t "> <STATIC : " s t a t i c "> <STRICTFP : " s t r i c t f p "> <SUPER : " super "> <SWITCH : " s w i t c h "> <SYNCHRONIZED : " s y n c h r o n i z e d "> <THIS : " t h i s "> <THROW: " throw "> <THROWS: " throws "> <TRANSIENT : " t r a n s i e n t "> <TRUE : " t r u e "> <TRY : " t r y "> <VOID : " v o i d "> <VOLATILE : " v o l a t i l e "> <WHILE : " w h i l e "> <CDATA : " < ! [ CDATA[ " > / ∗ LITERALS ∗ / <DEFAULT , JSP_STATE , JSP_JAVA> TOKEN : { <INTEGER_LITERAL : <DECIMAL_LITERAL> ( [ " l " , " L " ] ) ? | <HEX_LITERAL> ( [ " l " , " L " ] ) ? | < BINARY_LITERAL> ( [ " l " , " L " ] ) ? | <OCTAL_LITERAL> ( [ " l " , " L " ] ) ?> | <#DECIMAL_LITERAL : [ " 1 " − " 9 " ] ( [ " 0 " − " 9 " ] ) ∗> | <#HEX_LITERAL : " 0 " [ " x " , " X " ] ( [ " 0 " − " 9 " , " a " −" f " , " A" −"F " ] ) +> | <#BINARY_LITERAL : " 0 " [ " b " , " B " ] [ " 0 " , " 1 " ] ( ( [ " 0 " , " 1 " , " _ " ] ) ∗ [ " 0 " , " 1 " ] ) ?> | <#OCTAL_LITERAL : " 0 " ( [ " 0 " − " 7 " ] ) ∗> | <FLOATING_POINT_LITERAL : ( [ " 0 " − " 9 " ] ) + " . " ( [ " 0 " − " 9 " ] ) ∗ (<EXPONENT>) ? ( [ " f " , " F " , " d " , " D " ] ) ? | " . " ( [ " 0 " − " 9 " ] ) + (<EXPONENT>) ? ( [ " f " , " F " , " d " , " D " ] ) ? | ( [ " 0 " − " 9 " ] ) + < EXPONENT> ( [ " f " , " F " , " d " , " D " ] ) ? | ( [ " 0 " − " 9 " ] ) + (<EXPONENT>) ? [ " f " , " F " , " d " , " D" ] > | <HEX_FLOATING_POINT_LITERAL : (<HEX_LITERAL> ( " . " ) ? | " 0 " [ " x " , " X " ] ( [ " 0 " − " 9 " , " a " −" f " , " A" −"F " ] ( ( [ " 0 " − " 9 " , " a " −" f " , " A" −"F " , " _ " ] ) ∗ [ " 0 " − " 9 " , " a " −" f " , " A" −"F " ] ) ? ) ? " . " [ " 0 " − " 9 " , " a " −" f " , " A" −"F " ] ( ( [ " 0 " − " 9 " , " a " −" f " , " A" −"F " , " _ " ] ) ∗ [ " 0 " − " 9 " , " a " −" f " , " A" −" F " ] ) ?) [ " p " , "P " ] ( [ " + " , " − " ] ) ? [ " 0 " − " 9 " ] ( ( [ " 0 " − " 9 " , " _ " ] ) ∗ [ " 0 " − " 9 " ] ) ? ( [ " f " , " F " , " d " , " D " ] ) ?> | <#EXPONENT: [ " e " , " E " ] ( [ " + " , " − " ] ) ? ( [ " 0 " − " 9 " ] ) +> | <CHARACTER_LITERAL : " \ ’ " ( ~ [ " \ ’ " , " \ \ " , " \ n " , " \ r " ] | " \ \ " ( [ " n " , " t " , " b " , " r " , " f " , " \ \ " , " \ ’ " , " \ " " ] | [ " 0 " − " 7 " ] ( [ " 0 " − " 7 " ] ) ? | [ " 0 " − " 3 " ] [ " 0 " − " 7 " ] [ " 0 " − " 7 " ] ) | "\\u xix Luís Laranjeira - PJMAS " [ " 0 " − " 9 " , " A" −"F " , " a " −" f " ] [ " 0 " − " 9 " , " A" −"F " , " a " −" f " ] [ " 0 " − " 9 " , " A" −"F " , " a " −" f " ] [ " 0 " − " 9 " , " A" −"F " , " a " −" f " ] ) " \ ’ " > | <STRING_LITERAL : " \ " " ( ~ [ " \ " " , " \ \ " , " \ n " , " \ r " ] | " \ \ " ( [ " n " , " t " , " b " , " r " , " f " , " \ \ " , " \ ’ " , " \ " " ] | [ " 0 " − " 7 " ] ( [ " 0 " − " 7 " ] ) ? | [ " 0 " − " 3 " ] [ " 0 " − " 7 " ] [ " 0 " − " 7 " ] ) | "\\u " [ " 0 " − " 9 " , " A" −"F " , " a " −" f " ] [ " 0 " − " 9 " , " A" −"F " , " a " −" f " ] [ " 0 " − " 9 " , " A" −"F " , " a " −" f " ] [ " 0 " − " 9 " , " A" −"F " , " a " −" f " ] ) ∗ " \ " " > } / ∗ SEPARATORS ∗ / <DEFAULT , JSP_JAVA> TOKEN : { <LPAREN : " ( " > | <RPAREN: " ) "> | <LBRACE : " { " > | <RBRACE : " } " > | <LBRACKET : " [ " > | <RBRACKET : " ] " > | <SEMICOLON : " ; " > | <COMMA: " , " > | <DOT : " . " > | <VARARG : " . . . " > } / ∗ OPERATORS ∗ / <DEFAULT , JSP_JAVA> TOKEN : { <ASSIGN : "=" > | <LT : " <" > | <BANG: " ! " > | <TILDE : "~" > | <HOOK: " ? " > | <COLON: " : " > | <EQ : "=="> | <LE : "<="> | <GE : ">="> | <NE: "!=" > | <SC_OR : " | | " > | <SC_AND : "&&" > | <INCR : "++"> | <DECR : "−−"> | <PLUS : "+" > | <MINUS : "−"> | <STAR : " ∗ " > | <SLASH : " / " > | <BIT_AND : "&" > | <BIT_OR : " | " > | <XOR : " ^ " > | <REM: "%" > | <PLUSASSIGN : "+="> | <MINUSASSIGN : "−="> | <STARASSIGN : "∗=" > | <SLASHASSIGN : "/=" > | <ANDASSIGN : "&="> | <ORASSIGN : "|=" > | <XORASSIGN : "^=" > | <REMASSIGN : "%="> | <LSHIFTASSIGN : "<<="> | <RSIGNEDSHIFTASSIGN : ">>="> | <RUNSIGNEDSHIFTASSIGN : ">>>="> | <ATTRIBUTE : "@"> | <GT : " >" > } / ∗ IDENTIFIERS ∗ / xx Luís Laranjeira - PJMAS <DEFAULT , JSP_JAVA> TOKEN : { <IDENTIFIER : <LETTER> (<PART_LETTER>)∗> | <#LETTER : [ " $ " , " A" −" Z " , " _ " , " a " −" z " ] > | <#PART_LETTER : [ " − " , " $ " , " 0 " − " 9 " , " A" −" Z " , " _ " , " a " −" z " ] > } <JSP_STATE> TOKEN : { <JSP_IDENTIFIER : <JSP_LETTER> (<JSP_PART_LETTER>)∗> | <#JSP_LETTER : [ " $ " , " A" −" Z " , " _ " , " a " −" z " ] > | <#JSP_PART_LETTER : [ " − " , " $ " , " 0 " − " 9 " , " A" −" Z " , " _ " , " a " −" z " ] > } / ∗GRAMMAR∗ / ASTRoot := ( ( ( A n n o t a t i o n ) ∗ PackageDeclaration ) ? ( I n c l u d e S t a t e m e n t ) ∗ ( T y p e D e c l a r a t i o n ) ∗ | ( JspPage ) ∗ ) <EOF> JspPage := ( J s p D i r e c t i v e | J s p D e c l a r a t i o n | JspComment | J s p S t a t e m e n t | JspTagStatement | HtmlBlock ) JspTagStatement := <JSP_JSPTAG_BEGIN> J s p S t a n d a r d A c t i o n J s p S t a n d a r d A c t i o n := ( ( <JSP_PLUGIN> | <JSP_INVOKE> | <JSP_DO_BODY> | <JSP_ELEMENT> | <JSP_OUTPUT> | <JSP_ATTRIBUTE> | <JSP_IDENTIFIER> ) ( J s p S t a n d a r d A c t i o n P a r a m e t e r s ) ∗ ( <JSP_JSPTAG_END> | <JSP_JSPTAG_CLOSE> ( JspPage ) ∗ <JSP_JSPTAG_CLOSE_BEGIN> ( <JSP_PLUGIN> | <JSP_INVOKE> | <JSP_DO_BODY> | < JSP_ELEMENT> | <JSP_OUTPUT> | <JSP_ATTRIBUTE> | <JSP_IDENTIFIER> ) < JSP_JSPTAG_CLOSE> ) | <JSP_USE_BEAN> JspStandardActionUseBean ( <JSP_JSPTAG_END> | <JSP_JSPTAG_CLOSE> ( JspPage ) ∗ <JSP_JSPTAG_CLOSE_BEGIN> <JSP_USE_BEAN> < JSP_JSPTAG_CLOSE> ) | <JSP_GET_PROPERTY> J s p S t a n d a r d A c t i o n G e t P r o p e r t y ( < JSP_JSPTAG_END> | <JSP_JSPTAG_CLOSE> ( JspPage ) ∗ <JSP_JSPTAG_CLOSE_BEGIN> < JSP_GET_PROPERTY> <JSP_JSPTAG_CLOSE> ) | <JSP_SET_PROPERTY> J s p S t a n d a r d A c t i o n S e t P r o p e r t y ( <JSP_JSPTAG_END> | <JSP_JSPTAG_CLOSE> ( JspPage ) ∗ <JSP_JSPTAG_CLOSE_BEGIN> <JSP_SET_PROPERTY> <JSP_JSPTAG_CLOSE> ) | < JSP_INCLUDE> J s p S t a n d a r d A c t i o n I n c l u d e ( <JSP_JSPTAG_END> | <JSP_JSPTAG_CLOSE> ( RequestArguments ) ? <JSP_JSPTAG_CLOSE_BEGIN> <JSP_INCLUDE> <JSP_JSPTAG_CLOSE> ) | <JSP_PARAMS> ( J s p S t a n d a r d A c t i o n P a r a m e t e r s ) ∗ ( <JSP_JSPTAG_END> | < JSP_JSPTAG_CLOSE> ( RequestArguments ) <JSP_JSPTAG_CLOSE_BEGIN> <JSP_PARAMS> < JSP_JSPTAG_CLOSE> ) | <JSP_PARAM> J s p S t a n d a r d A c t i o n P a r a m e t e r ( <JSP_JSPTAG_END> | <JSP_JSPTAG_CLOSE> ( JspPage ) ∗ <JSP_JSPTAG_CLOSE_BEGIN> <JSP_PARAM> < JSP_JSPTAG_CLOSE> ) | <JSP_FORWARD> J s p S t a n d a r d A c t i o n I n c l u d e ( <JSP_JSPTAG_END> | <JSP_JSPTAG_CLOSE> ( RequestArguments ) ? <JSP_JSPTAG_CLOSE_BEGIN> <JSP_FORWARD > <JSP_JSPTAG_CLOSE> ) ) JspStandardActionParameter RequestArguments := := ( JspStandardActionParameters ) ∗ ( JspPage )+ JspStandardActionUseBean := ( JspStandardActionParameters ) ∗ JspStandardActionGetProperty := ( JspStandardActionParameters ) ∗ JspStandardActionSetProperty := ( JspStandardActionParameters ) ∗ JspStandardActionInclude ( JspStandardActionParameters ) ∗ := J s p S t a n d a r d A c t i o n P a r a m e t e r s := ( <JSP_SCOPE> | <JSP_NAME> | <JSP_PAGE> | < JSP_PROPERTY> | <JSP_VALUE> | <JSP_ID> | <JSP_CLASS> | <JSP_TYPE> | <JSP_PARAM> | <JSP_IDENTIFIER> ( <JSP_COLON> <JSP_IDENTIFIER> ) ∗ ) <JSP_ASSIGN> AttributeValue xxi Luís Laranjeira - PJMAS A t t r i b u t e V a l u e := ( <JSP_QUOTE> ( <JSP_EXPR> E x p r e s s i o n S t a t e m e n t <JSP_END> | ( < CONSTANT> | <JSP_PELICA> ) ( ( <CONSTANT> | <JSP_PELICA> | <JSP_EXPR> ) ) ∗ ) ? < JSP_QUOTE> | <JSP_PELICA> ( <JSP_EXPR> E x p r e s s i o n S t a t e m e n t <JSP_END> | ( < CONSTANT> | <JSP_QUOTE> ) ( ( <CONSTANT> | <JSP_QUOTE> | <JSP_EXPR> ) ) ∗ ) ? < JSP_PELICA> ) J s p S t a t e m e n t := <JSP_BEGIN> ( StatementWithoutEmbeddedHtml ) ∗ ( <JSP_END> | < JSP_SCRIPTLET_XML_END> ) | <JSP_SCRIPTLET_XML> ( ( StatementWithoutEmbeddedHtml ) ∗ ( <JSP_END> | < JSP_SCRIPTLET_XML_END> ) | <CDATA> ( StatementWithoutEmbeddedHtml ) ∗ " ] " " ] " " > " ( <JSP_END> | <JSP_SCRIPTLET_XML_END> ) ) HtmlBlock := ( <HTML> | <JSP_EXPR> E x p r e s s i o n ( " ; " ) ? <JSP_END> | < JSP_EXPRESSION_XML> ( E x p r e s s i o n ( " ; " ) ? <JSP_EXPRESSION_XML_END> | <CDATA> E x p r e s s i o n ( " ; " ) ? " ] " " ] " " > " <JSP_EXPRESSION_XML_END> ) | JspCheck ( <HTML> ) ? | <HTML_OTHER> ) JspCheck := ( " < " | " < ! " | <IDENTIFIER> | <INTEGER_LITERAL> | < FLOATING_POINT_LITERAL> | <CHARACTER_LITERAL> | <STRING_LITERAL> ) J s p D i r e c t i v e := ( ( <JSP_DIRECTIVE> ) J s p D i r e c t i v e L i s t <JSP_STATE_END> | < JSP_DIRECTIVE_XML> J s p D i r e c t i v e L i s t ( <JSP_JSPTAG_END> | <JSP_JSPTAG_CLOSE> ( JspPage ) ∗ <JSP_DIRECTIVE_XML_CLOSE> J s p D i r e c t i v e L i s t <JSP_JSPTAG_CLOSE> ) ) J s p D i r e c t i v e L i s t := <JSP_TAG> ( T a g D i r e c t i v e L i s t ) ∗ | <JSP_TAGLIB> ( T a g L i b D i r e c t i v e L i s t ) ∗ | <JSP_PAGE> ( P a g e D i r e c t i v e L i s t ) ∗ | <JSP_INCLUDE> ( I n c l u d e D i r e c t i v e L i s t ) ? | <JSP_ATTRIBUTE> ( A t r r i b u t e D i r e c t i v e L i s t ) ∗ | < JSP_VARIABLE> ( V a r i a b l e D i r e c t i v e L i s t ) ∗ V a r i a b l e D i r e c t i v e L i s t := ( <JSP_NAME_GIVEN> | <JSP_VARIABLE_CLASS> | <JSP_SCOPE> | < JSP_DECLARE> | <JSP_DESCRIPTION> | <JSP_NAME_FROM_ATTRIBUTE> | <JSP_ALIAS> ) < JSP_ASSIGN> J s p C o n s t a n t IncludeDirectiveList := <JSP_FILE> <JSP_ASSIGN> J s p C o n s t a n t A t r r i b u t e D i r e c t i v e L i s t := ( <JSP_NAME> | <JSP_REQUIRED> | <JSP_FRAGMENT> | < JSP_RTEXPRVALUE> | <JSP_TYPE> | <JSP_DESCRIPTION> ) <JSP_ASSIGN> J s p C o n s t a n t T a g D i r e c t i v e L i s t := ( <JSP_DISPLAY_NAME> | <JSP_BODY_CONTENT> | < JSP_DYNAMIC_ATTRIBUTES> | <JSP_SMALL_ICON> | <JSP_LARGE_ICON> | <JSP_DESCRIPTION > | <JSP_EXAMPLE> | <JSP_LANGUAGE> | <JSP_IMPORT> | <JSP_PAGEENCODING> | < JSP_ISELIGNORED> ) <JSP_ASSIGN> J s p C o n s t a n t T a g L i b D i r e c t i v e L i s t := JspConstant ( <JSP_URI> | <JSP_PREFIX> | <JSP_TAGDIR> ) <JSP_ASSIGN> P a g e D i r e c t i v e L i s t := ( ( <JSP_LANGUAGE> | <JSP_EXTENDS> | <JSP_SESSION> | < JSP_BUFFER> | <JSP_AUTOFLUSH> | <JSP_ISTHREADSAFE> | <JSP_INFO> | < JSP_ISERRORPAGE> | <JSP_CONTENTTYPE> | <JSP_PAGEENCODING> | <JSP_ISELIGNORED> ) <JSP_ASSIGN> J s p C o n s t a n t | <JSP_IMPORT> <JSP_ASSIGN> ( J s p P a g e I n c l u d e s ) | < JSP_ERRORPAGE> <JSP_ASSIGN> ( J s p P a g e I n c l u d e s ) ) J s p P a g e I n c l u d e s := ( <JSP_QUOTE> ( J s p P a g e I n c l u d e ( <JSP_COMMA> ) ? ) ∗ <JSP_QUOTE> | <JSP_PELICA> ( J s p P a g e I n c l u d e ( <JSP_COMMA> ) ? ) ∗ <JSP_PELICA> ) JspPageInclude := <JSP_IMPORT_TEXT> J s p C o n s t a n t := ( <INTEGER_LITERAL> | <FLOATING_POINT_LITERAL> | <CHARACTER_LITERAL> | <STRING_LITERAL> | <JSP_NULL> | <JSP_FALSE> | <JSP_TRUE> ) J s p D e c l a r a t i o n := ( ( <JSP_DECLARATION> ) ( MemberDeclaration ) ∗ ( <JSP_END> | < JSP_DECLARATION_XML_END> ) | <JSP_DECLARATION_XML> ( ( MemberDeclaration ) ∗ ( < xxii Luís Laranjeira - PJMAS JSP_END> | <JSP_DECLARATION_XML_END> ) | <CDATA> ( MemberDeclaration ) ∗ " ] " " > " ( <JSP_END> | <JSP_DECLARATION_XML_END> ) ) ) JspComment := "]" <JSP_COMMENT_BEGIN> <JSP_COMMENT_END> PackageDeclaration IncludeStatement := := <PACKAGE> P o s t f i x E x p r e s s i o n ";" <IMPORT> ( <STATIC> ) ? P o s t f i x E x p r e s s i o n ";" P o s t f i x E x p r e s s i o n := Primary ( " . " ( P o s t f i x E x p r e s s i o n | Constants2 ) | ArgumentExpressionList | ( " [ " ( Expression ) ? " ] " ) ) ∗ ArrayInitializer Constants2 := := " { " ( Expression ( " , " ) ? ) ∗ " } " ( <CLASS> | <ENUM> ) Primary := ( ( TypeArguments ) ? V a r i a b l e | Constant | <SUPER> | <VOID> | C l a s s I n s t a n t i a t i o n | BasicType | " ( " E x p r e s s i o n " ) " ) Variable := <IDENTIFIER> V a r i a b l e D e c l a r a t i o n := Variable2 ) ∗ V a r i a b l e 2 := ( A n n o t a t i o n ) ∗ ( M o d i f i e r ) ∗ Type ( <IDENTIFIER> ( "[" "]" "..." ) ? Variable2 ( " , " ) ∗ ( "=" Expression ) ? Constant := ( <INTEGER_LITERAL> | <FLOATING_POINT_LITERAL> | < HEX_FLOATING_POINT_LITERAL> | <CHARACTER_LITERAL> | <STRING_LITERAL> | " ∗ " | < NULL> | <FALSE> | <TRUE> | <THIS> ) Annotation := "@" <IDENTIFIER> ( " . " <IDENTIFIER> ) ∗ ( A r g u m e n t E x p r e s s i o n L i s t ) ? BasicType := ( <BYTE> | <SHORT> | <CHAR> | <INT> | <LONG> | <FLOAT> | <DOUBLE> | < BOOLEAN> ) T y p e D e c l a r a t i o n := | ";" ClassOrInterfaceDeclaration C l a s s O r I n t e r f a c e D e c l a r a t i o n := InterfaceDeclaration ) ( ( Annotation | Modifier ) ) ∗ ( ClassDeclaration | M o d i f i e r := ( <PUBLIC> | <PROTECTED> | <PRIVATE> | <STATIC> | <ABSTRACT> | <FINAL> | <NATIVE> | <SYNCHRONIZED> | <TRANSIENT> | <VOLATILE> | <STRICTFP> ) C l a s s D e c l a r a t i o n := | EnumDeclaration NormalClassDeclaration N o r m a l C l a s s D e c l a r a t i o n := <CLASS> <IDENTIFIER> ( TypeParameters ) ? ( <EXTENDS> Type ) ? ( <IMPLEMENTS> T y p e L i s t ) ? ClassMembers EnumDeclaration := EnumBody := <ENUM> <IDENTIFIER> ( <IMPLEMENTS> T y p e L i s t ) ? EnumBody " { " ( EnumConstants ) ? ( " , " ) ? ( EnumBodyDeclarations ) ? " } " EnumConstants := EnumConstant ( " , " EnumConstant ) ∗ EnumConstant := ( A n n o t a t i o n ) ∗ <IDENTIFIER> ( A r g u m e n t E x p r e s s i o n L i s t ) ? ( ClassMembers ) ? EnumBodyDeclarations := ";" ( MemberDeclaration ) ∗ InterfaceDeclaration := NormalInterfaceDeclaration xxiii Luís Laranjeira - PJMAS | AnnotationTypeDeclaration N o r m a l I n t e r f a c e D e c l a r a t i o n := <INTERFACE> <IDENTIFIER> ( TypeParameters ) ? ( < EXTENDS> T y p e L i s t ) ? ClassMembers A n n o t a t i o n T y p e D e c l a r a t i o n := AnnotationTypeBody := "@" <INTERFACE> <IDENTIFIER> AnnotationTypeBody " { " ( AnnotationBodyDeclaration ) ∗ " } " A n n o t a t i o n B o d y D e c l a r a t i o n := ( A n n o t a t i o n ) ∗ ( M o d i f i e r ) ∗ ( AnnotationMathodRest " ; " | AnnotationTypeDeclaration | Expression " ; " | NormalClassDeclaration | EnumDeclaration | N o r m a l I n t e r f a c e D e c l a r a t i o n ) AnnotationMathodRest := Type <IDENTIFIER> " ( " Annotation | Expression ) ) ? TypeParameters := TypeParameter := ") " ( TypeList ReferenceType ( " , " ReferenceType ) ∗ := ) ? ( <_DEFAULT> ( V a r i a b l e ( <EXTENDS> TypeBound ) ? ReferenceType ( " & " ReferenceType ) ∗ ClassMembers "]" " < " TypeParameter ( " , " TypeParameter ) ∗ " > " TypeBound := := "[" " { " ( MemberDeclaration ) ∗ " } " MemberDeclaration := ( ( <STATIC> ) ? CompoundStatement | V a r i a b l e D e c l a r a t i o n " ; " | ( ( Modifier | Annotation ) ) ∗ ( ClassDeclaration | NormalInterfaceDeclaration | LabeledStatement | ( TypeParameters ) ? <IDENTIFIER> " ( " ( P a r a m e t e r L i s t ) ? " ) " ( ThrowsStatement ) ? ClassConstructorCompoundStatement | ( TypeParameters ) ? ( Type | <VOID> ) <IDENTIFIER> " ( " ( P a r a m e t e r L i s t ) ? " ) " ( ThrowsStatement ) ? ( CompoundStatement | " ; " ) | " ; " ) ) GenericMethodOrConstructorRest := ( <IDENTIFIER> " ( " ( P a r a m e t e r L i s t ) ? " ) " ( ThrowsStatement ) ? CompoundStatement | ( Type | <VOID> ) <IDENTIFIER> " ( " P a r a m e t e r L i s t " ) " ( " [ " " ] " ) ∗ ( ThrowsStatement ) ? ( CompoundStatement | " ; " ) ThrowsStatement := P a r a m e t e r L i s t := Parameter := <THROWS> P o s t f i x E x p r e s s i o n ( " , " P o s t f i x E x p r e s s i o n ) ∗ Parameter ( " , " Parameter ) ∗ ( <FINAL> | A n n o t a t i o n ) ∗ Type ( CompoundStatement := "..." ) ? Variable ( "[" "]" )∗ " { " ( Statement ) ∗ " } " ClassConstructorCompoundStatement := Statement ) ∗ " } " E x p l i c i t C o n s t r u c t o r I n v o c a t i o n := " { " ( ExplicitConstructorInvocation ) ? ( ( TypeArguments P o s t f i x E x p r e s s i o n ";" ) JspPageWithoutJspStatement := ( J s p D i r e c t i v e | J s p D e c l a r a t i o n | JspComment | JspTagStatement | HtmlBlock ) Statement := ( " ; " | C l a s s O r I n t e r f a c e D e c l a r a t i o n | CompoundStatement | LabeledStatement | SynchronizedStatement | E x p r e s s i o n S t a t e m e n t ( " ; " ) ? | JumpStatement " ; " | S e l e c t i o n S t a t e m e n t | I t e r a t i o n S t a t e m e n t | ThrowStatement | TryStatement | EmbeddedHtml ) StatementWithoutEmbeddedHtml := ( " ; " | C l a s s O r I n t e r f a c e D e c l a r a t i o n | CompoundStatement | LabeledStatement | SynchronizedStatement | E x p r e s s i o n S t a t e m e n t ( " ; " ) ? | JumpStatement " ; " | S e l e c t i o n S t a t e m e n t | xxiv ) Luís Laranjeira - PJMAS I t e r a t i o n S t a t e m e n t | ThrowStatement | TryStatement ) EmbeddedHtml := ( ( <JSP_END> | <JSP_SCRIPTLET_XML_END> ) ( JspPageWithoutJspStatement ) ∗ ( <JSP_BEGIN> | <JSP_SCRIPTLET_XML> ) ) JumpStatement := ( <BREAK> ( <IDENTIFIER> ) ? | <CONTINUE> ( <IDENTIFIER> ) ? | < RETURN> ( E x p r e s s i o n ) ? ) LabeledStatement := ( <IDENTIFIER> " : " Statement | <CASE> E x p r e s s i o n " : " ( Statement ) ∗ | <_DEFAULT> " : " ( Statement ) ∗ | <ASSERT> E x p r e s s i o n ( " : " Expression ) ? " ; " ) S e l e c t i o n S t a t e m e n t := ( <IF> " ( " E x p r e s s i o n " ) " Statement ( <ELSE> Statement ) ? | < SWITCH> " ( " E x p r e s s i o n " ) " Statement ) I t e r a t i o n S t a t e m e n t := ( <WHILE> " ( " E x p r e s s i o n " ) " Statement | <DO> Statement < WHILE> " ( " E x p r e s s i o n " ) " " ; " | <FOR> " ( " ( E x p r e s s i o n " : " E x p r e s s i o n | ( Expression ( " , " Expression ) ∗ ) ? " ; " ( Expression ) ? " ; " ( Expression ( " , " E x p r e s s i o n ) ∗ ) ? ) " ) " Statement ) ThrowStatement := <THROW> E x p r e s s i o n " ; " SynchronizedStatement := <SYNCHRONIZED> " ( " E x p r e s s i o n " ) " Statement TryStatement := <TRY> ( CompoundStatement ( ( CatchClause )+ ( F i n a l l y ) ? | F i n a l l y ) | TryUsing CompoundStatement ( ( CatchClause )+ ) ? ( F i n a l l y ) ? ) TryUsing F i n a l l y := := " ( " Expression ( ";" ) ? ( Expression ( ";" )? )∗ ") " <FINALLY> CompoundStatement CatchClause := <CATCH> " ( " ( M o d i f i e r ) ∗ <IDENTIFIER> ( " . " <IDENTIFIER> ) ∗ ( IDENTIFIER> ( " . " <IDENTIFIER> ) ∗ ) ∗ V a r i a b l e " ) " CompoundStatement Type := ( ReferenceType | BasicType ) ReferenceType := ( BasicType ( C l a s s O r I n t e r f a c e T y p e := TypeArguments ) ? ) ∗ "[" "]" )+ | C l a s s O r I n t e r f a c e T y p e ( <IDENTIFIER> ( TypeArguments ) ? ( "[" " < " ( TypeArgument ( " , " TypeArgument ) ∗ ) ? " > " TypeArgument := ( ReferenceType | Wildcard ) Wildcard " ? " ( <EXTENDS> ReferenceType | <SUPER> ReferenceType ) ? := E x p r e s s i o n S t a t e m e n t := := "]" )∗ ) " . " <IDENTIFIER> ( TypeArguments := Expression "|" < Expression AssignmentExpression A s s i g n m e n t E x p r e s s i o n := ( V a r i a b l e D e c l a r a t i o n | C o n d i t i o n a l E x p r e s s i o n ( AssignmentOperator E x p r e s s i o n ) ? ) C o n d i t i o n a l E x p r e s s i o n := Logical_Or_Expression ( " ? " Expression " : " Expression ) ? L o g i c a l _ O r _ E x p r e s s i o n := Logical_And_Expression ( Logical_And_Expression := B i t w i s e O r E x p r e s s i o n := BitwiseXorExpression ( " | | " Logical_Or_Expression ) ? BitwiseOrExpression ( "&&" Logical_And_Expression ) ? xxv " | " BitwiseOrExpression ) ? Luís Laranjeira - PJMAS BitwiseXorExpression := BitwiseAndExpression ( " ^ " BitwiseXorExpression ) ? BitwiseAndExpression := EqualityExpression ( " & " BitwiseAndExpression ) ? EqualityExpression := R e l a t i o n a l E x p r e s s i o n ( ( "==" | " ! = " ) E q u a l i t y E x p r e s s i o n ) ? R e l a t i o n a l E x p r e s s i o n := S h i f t E x p r e s s i o n ( ( " < " | " > " | " <=" | " >=" ) RelationalExpression ) ? S h i f t E x p r e s s i o n := A d d i t i v e E x p r e s s i o n ( ( " < " " < " | " > " " > " " > " | " > " " > " ) ShiftExpression ) ? AdditiveExpression ? := M u l t i p l i c a t i v e E x p r e s s i o n ( ( " + " | " −" ) A d d i t i v e E x p r e s s i o n ) M u l t i p l i c a t i v e E x p r e s s i o n := UnaryExpression ( ( " ∗ " | MultiplicativeExpression ) ? CastExpression := UnaryExpression := ( "(" := P o s t f i x I n c D e c E x p r e s s i o n := InstanceOfExpression := | "%" ) ( Type ) " ) " E x p r e s s i o n | I n s t a n c e O f E x p r e s s i o n ) ( " & " | " −" | " ~ " | PrefixIncDecExpression "/" "!" | "+" ) ∗ PrefixIncDecExpression ( "++" | "−−" ) ∗ P o s t f i x I n c D e c E x p r e s s i o n C a s t E x p r e s s i o n ( ( "++" | "−−" ) ) ∗ ( P o s t f i x E x p r e s s i o n | A n n o t a t i o n ) ( <INSTANCEOF> Type ) ? C l a s s I n s t a n t i a t i o n := ( <NEW> ( TypeArguments ) ? Type ( " [ " ( E x p r e s s i o n ) ? " ] " ( A r g u m e n t E x p r e s s i o n L i s t ) ? ( ( A r r a y I n i t i a l i z e r | ClassMembers ) ) ? | ArrayInitializer ) ArgumentExpressionList := "(" ( Expression ( " , " Expression ) ∗ ) ? " ) " AssignmentOperator := <ASSIGN> | <PLUSASSIGN> | <MINUSASSIGN> | <STARASSIGN> | < SLASHASSIGN> | <ANDASSIGN> | <ORASSIGN> | <XORASSIGN> | <REMASSIGN> | < LSHIFTASSIGN> | <RSIGNEDSHIFTASSIGN> | <RUNSIGNEDSHIFTASSIGN> xxvi )∗ Apêndice G Testes xxvii Luís Laranjeira - PJMAS G.1 G.1.1 Testes às Funcionalidades Testes à Linguagem Java ID Teste: 1 Data: 12/03/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Deteção de comentários. Descrição: Ficheiro Teste.java, com vários comentários diferentes. Conteúdo do ficheiro de input: / / t e s t with one l i n e comment /∗ ∗ t e s t with m u l t i −l i n e comment ∗/ /∗ ∗ ∗ t e s t e with o n l e l i n e comment ∗ ∗ @author L u i s L a r a n j e i r a ∗ @since now ∗/ / ∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗∗∗∗∗ COMMENT WITH STARS ∗∗∗∗∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ / Resultado Parsing Esperado: Parsing sem qualquer erro e árvore obtida preenchida corretamente. Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado: ASTRoot Resultado do Teste: Pass. xxviii Luís Laranjeira - PJMAS ID Teste: 2 Data: 13/03/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Deteção de Package e Imports Descrição: Ficheiro Teste.java, com declarações de Package e Imports. Conteúdo do ficheiro de input: package T e s t e s ; /∗ ∗ t e s t with m u l t i −l i n e comment ∗/ i m p o r t j a v a . u t i l . HashMap ; import java . io . ∗ ; Resultado Parsing Esperado: Parsing sem qualquer erro e árvore obtida preenchida corretamente. Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado: ASTRoot . PackageDeclaration ; . . Variable Variable : : Testes " n u l l " . IncludeStatement Include : : import . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . Variable Variable : : java " null " . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . Variable Variable : : u t i l " null " . . . . V a r i a b l e V a r i a b l e : : HashMap " n u l l " . IncludeStatement Include : : import . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . Variable Variable : : java " null " . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . Variable Variable : : io " null " . . . . Constant Constant : : s t a r : : ∗ Resultado do Teste: Pass. xxix Luís Laranjeira - PJMAS ID Teste: 3 Data: 16/03/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Declaração de Classes. Descrição: Ficheiro Teste.java, com declaração de uma classe com “extends” e “Implements”, no entanto englobando tipos diferentes e mais complexos que no teste anterior. Conteúdo do ficheiro de input: package T e s t e s ; p u b l i c c l a s s Teste extends A r r a y L i s t <S t r i n g > implements HashMap<S t r i n g , i n t [ ] [ ] > , HashTable<S t r i n g , Double>{ } Resultado Parsing Esperado: Parsing sem qualquer erro e árvore obtida preenchida corretamente. Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado: ASTRoot . PackageDeclaration ; . . Variable Variable : : Testes " n u l l " . N o r m a l C l a s s D e c l a r a t i o n C l a s s : : Teste e x t e n d s A r r a y L i s t <S t r i n g > implements HashTable< S t r i n g , Double> HashMap<S t r i n g , i n t [ ] [ ] > ( , ) . . Type > . . . ReferenceType > . . . . C l a s s O r I n t e r f a c e T y p e C l a s s : : A r r a y L i s t <S t r i n g > ( , ) . . . . . TypeArguments <S t r i n g > . . . . . . TypeArgument S t r i n g . . . . . . . ReferenceType S t r i n g . . . . . . . . ClassOrInterfaceType Class : : String ( , ) . . T y p e L i s t [ HashTable<S t r i n g , Double > , HashMap<S t r i n g , i n t [ ] [ ] > ] . . . ReferenceType > . . . . C l a s s O r I n t e r f a c e T y p e C l a s s : : HashMap<S t r i n g , i n t [ ] [ ] > ( , ) . . . . . TypeArguments <S t r i n g , i n t [ ] [ ] > . . . . . . TypeArgument S t r i n g . . . . . . . ReferenceType S t r i n g . . . . . . . . ClassOrInterfaceType Class : : String ( , ) . . . . . . TypeArgument ] . . . . . . . ReferenceType [ ] [ ] . . . . . . . . BasicType i n t . . . ReferenceType > . . . . C l a s s O r I n t e r f a c e T y p e C l a s s : : HashTable<S t r i n g , Double> ( , ) . . . . . TypeArguments <S t r i n g , Double> . . . . . . TypeArgument S t r i n g . . . . . . . ReferenceType S t r i n g . . . . . . . . ClassOrInterfaceType Class : : String ( , ) . . . . . . TypeArgument Double . . . . . . . ReferenceType Double . . . . . . . . C l a s s O r I n t e r f a c e T y p e C l a s s : : Double ( , ) . . ClassMembers } Resultado do Teste: Pass. xxx Luís Laranjeira - PJMAS ID Teste: 4 Data: 17/03/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Declaração de Enum. Descrição: Ficheiro Teste.java, com declaração de uma classe Enum com vários“Implements”. Conteúdo do ficheiro de input: package T e s t e s ; import java . io . S e r i a l i z a b l e ; p u b l i c enum Teste implements Foo , j a v a . u t i l . L i s t I t e r a t o r <E> , S e r i a l i z a b l e { } Resultado Parsing Esperado: Parsing sem qualquer erro e árvore obtida preenchida corretamente. Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado: ASTRoot . PackageDeclaration ; . . Variable Variable : : Testes " n u l l " . IncludeStatement Include : : import . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . Variable Variable : : java " null " . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . Variable Variable : : io " null " . . . . Variable Variable : : Serializable " null " . EnumDeclaration Enum : : Teste implements j a v a . u t i l . L i s t I t e r a t o r S e r i a l i z a b l e Foo . . T y p e L i s t [ j a v a . u t i l . L i s t I t e r a t o r , S e r i a l i z a b l e , Foo ] . . . ReferenceType Foo . . . . C l a s s O r I n t e r f a c e T y p e C l a s s : : Foo ( , ) . . . ReferenceType > . . . . ClassOrInterfaceType Class : : java . u t i l . L i s t I t e r a t o r ( , ) . . . . . TypeArguments <E> . . . . . . TypeArgument E . . . . . . . ReferenceType E . . . . . . . . ClassOrInterfaceType Class : : E ( , ) . . . ReferenceType S e r i a l i z a b l e . . . . ClassOrInterfaceType Class : : S e r i a l i z a b l e ( , ) . . EnumBody } Resultado do Teste: Pass. xxxi Luís Laranjeira - PJMAS ID Teste: 5 Data: 18/03/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Declaração de interface. Descrição: Ficheiro Teste.java, com declaração de uma classe Interface implements. Conteúdo do ficheiro de input: package T e s t e s ; p u b l i c i n t e r f a c e Teste implements S e r i a l i z a b l e { } Resultado Parsing Esperado: Erro de parsing, devido a não ser possível efetuar implements numa classe Interface. Resultado Parsing Obtido: Erro de parsing, encontrado um token não previsto, tal como esperado no teste. Output observado: E x c e p t i o n i n t h r e a d " main " com . dognaedis . codana . j a v a . p a r s e r . P a r s e E x c e p t i o n : Encountered " " implements " " implements " " a t l i n e 3 , column 2 4 . Was e x p e c t i n g one o f : " extends " . . . "{" . . . " <" . . . Resultado do Teste: Pass. xxxii Luís Laranjeira - PJMAS ID Teste: 6 Data: 18/03/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Declaração de interface. Descrição: Ficheiro Teste.java, com declaração de uma classe Interface com extends. Conteúdo do ficheiro de input: package T e s t e s ; p u b l i c i n t e r f a c e Teste <O> extends Foo{ } Resultado Parsing Esperado: Parsing sem qualquer erro e árvore obtida preenchida corretamente. Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado: ASTRoot . PackageDeclaration ; . . Variable Variable : : Testes " n u l l " . N o r m a l I n t e r f a c e D e c l a r a t i o n I n t e r f a c e : : Teste Foo . . TypeParameters > . . . TypeParameter O . . . . Variable Variable : :O " null " . . T y p e L i s t [ Foo ] . . . ReferenceType Foo . . . . C l a s s O r I n t e r f a c e T y p e C l a s s : : Foo ( , ) . . ClassMembers } Resultado do Teste: Pass. xxxiii Luís Laranjeira - PJMAS ID Teste: 7 Data: 22/03/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Variáveis/objetos e operações entre si. Descrição: Ficheiro Teste.java, com declaração de variáveis. Conteúdo do ficheiro de input: (...) p u b l i c c l a s s Teste { i n t v a r i a v e l =20 , j , i =8889 , k ; HashMap<S t r i n g , I n t e g e r > hash = new HashMap<S t r i n g , I n t e g e r > ( ) ; } Resultado Parsing Esperado: Parsing sem qualquer erro e árvore obtida preenchida corretamente. Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado: (...) . N o r m a l C l a s s D e c l a r a t i o n C l a s s : : Teste ( , ) . . ClassMembers } . . . MemberDeclaration ; . . . . VariableDeclaration k . . . . . Type i n t . . . . . . BasicType i n t . . . . . Variable2 Variable : : integer : : v a r i a v e l " null " . . . . . . Constant Constant : : i n t : : 2 0 . . . . . Variable2 Variable : : integer : : j " null " . . . . . Variable2 Variable : : integer : : i " null " . . . . . . Constant Constant : : i n t : : 8 8 8 9 . . . . . Variable2 Variable : : integer : : k " null " . . . MemberDeclaration ; . . . . VariableDeclaration ) . . . . . Type > . . . . . . ReferenceType > . . . . . . . C l a s s O r I n t e r f a c e T y p e C l a s s : : HashMap<S t r i n g , I n t e g e r > ( , ) . . . . . . . . TypeArguments <S t r i n g , I n t e g e r > . . . . . . . . . TypeArgument S t r i n g . . . . . . . . . . ReferenceType S t r i n g . . . . . . . . . . . ClassOrInterfaceType Class : : String ( , ) . . . . . . . . . TypeArgument I n t e g e r . . . . . . . . . . ReferenceType I n t e g e r . . . . . . . . . . . ClassOrInterfaceType Class : : Integer ( , ) . . . . . V a r i a b l e 2 V a r i a b l e : : o b j e c t : : hash " C l a s s : : HashMap<S t r i n g , I n t e g e r > ( , ) " . . . . . . ClassInstantiation ) . . . . . . . Type > . . . . . . . . ReferenceType > . . . . . . . . . C l a s s O r I n t e r f a c e T y p e C l a s s : : HashMap<S t r i n g , I n t e g e r > ( , ) . . . . . . . . . . TypeArguments <S t r i n g , I n t e g e r > . . . . . . . . . . . TypeArgument S t r i n g . . . . . . . . . . . . ReferenceType S t r i n g . . . . . . . . . . . . . ClassOrInterfaceType Class : : String ( , ) . . . . . . . . . . . TypeArgument I n t e g e r . . . . . . . . . . . . ReferenceType I n t e g e r . . . . . . . . . . . . . ClassOrInterfaceType Class : : Integer ( , ) xxxiv Luís Laranjeira - PJMAS . . . . . . . ArgumentExpressionList ) Resultado do Teste: Pass. xxxv Luís Laranjeira - PJMAS ID Teste: 8 Data: 26/03/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Variáveis/objetos e funções. Descrição: Ficheiro Teste.java, com declaração de variáveis e funções com e sem retorno de objetos. Conteúdo do ficheiro de input: package T e s t e s ; p u b l i c c l a s s Teste { p r i v a t e i n t v a r i a v e l =20; public void funcao ( ) { } } public Object [ ] [ ] } funcao ( i n t a ) { Resultado Parsing Esperado: Parsing sem qualquer erro e árvore obtida preenchida corretamente. Resultado Parsing Obtido: Parsing sem qualquer erro , no entanto a árvore resultante não corresponde ao esperado, os nós das funções não contêm o tipo de objetos que são retornados pela função. Output Esperado: ASTRoot . PackageDeclaration ; . . Variable Variable : : Testes " n u l l " . N o r m a l C l a s s D e c l a r a t i o n C l a s s : : Teste ( , ) . . ClassMembers } . . . MemberDeclaration ; . . . . V a r i a b l e D e c l a r a t i o n 20 . . . . . Type i n t . . . . . . BasicType i n t . . . . . Variable2 Variable : : integer : : v a r i a v e l private " null " . . . . . . Constant Constant : : i n t : : 2 0 . . . MemberDeclaration F u n c t i o n : : f u n c a o p u b l i c v o i d . . . . CompoundStatement } . . . MemberDeclaration F u n c t i o n : : f u n c a o p u b l i c O b j e c t [ ] [ ] . . . . Type ] . . . . . ReferenceType [ ] [ ] . . . . . . ClassOrInterfaceType Class : : Object ( , ) . . . . ParameterList a . . . . . Parameter V a r i a b l e : : a " n u l l " . . . . . . Type i n t . . . . . . . BasicType i n t . . . . . . Variable Variable : : a " null " . . . . CompoundStatement } Output observado: xxxvi Luís Laranjeira - PJMAS ASTRoot . PackageDeclaration ; . . Variable Variable : : Testes " n u l l " . N o r m a l C l a s s D e c l a r a t i o n C l a s s : : Teste ( , ) . . ClassMembers } . . . MemberDeclaration ; . . . . V a r i a b l e D e c l a r a t i o n 20 . . . . . Type i n t . . . . . . BasicType i n t . . . . . Variable2 Variable : : integer : : v a r i a v e l private " null " . . . . . . Constant Constant : : i n t : : 2 0 . . . MemberDeclaration F u n c t i o n : : f u n c a o p u b l i c . . . . CompoundStatement } . . . MemberDeclaration F u n c t i o n : : f u n c a o p u b l i c . . . . Type ] . . . . . ReferenceType [ ] [ ] . . . . . . ClassOrInterfaceType Class : : Object ( , ) . . . . ParameterList a . . . . . Parameter V a r i a b l e : : a " n u l l " . . . . . . Type i n t . . . . . . . BasicType i n t . . . . . . Variable Variable : : a " null " . . . . CompoundStatement } Resultado do Teste: Fail. Procedimento; O autor deve corrigir a causa do problema e voltar a efetuar novamente o teste em questão. xxxvii Luís Laranjeira - PJMAS ID Teste: 9 Data: 26/03/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Variáveis/objetos e funções, teste igual o anterior, após resolução do problema detetado anteriormente. Descrição: Ficheiro Teste.java, com declaração de variáveis e funções com e sem retorno de objetos. Conteúdo do ficheiro de input: package T e s t e s ; p u b l i c c l a s s Teste { p r i v a t e i n t v a r i a v e l =20; public void funcao ( ) { } public Object [ ] [ ] } funcao ( i n t a ) { } Resultado Parsing Esperado: Parsing sem qualquer erro e árvore obtida preenchida corretamente. Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado: ASTRoot . PackageDeclaration ; . . Variable Variable : : Testes " n u l l " . N o r m a l C l a s s D e c l a r a t i o n C l a s s : : Teste ( , ) . . ClassMembers } . . . MemberDeclaration ; . . . . V a r i a b l e D e c l a r a t i o n 20 . . . . . Type i n t . . . . . . BasicType i n t . . . . . Variable2 Variable : : integer : : v a r i a v e l private " null " . . . . . . Constant Constant : : i n t : : 2 0 . . . MemberDeclaration F u n c t i o n : : f u n c a o p u b l i c v o i d . . . . CompoundStatement } . . . MemberDeclaration F u n c t i o n : : f u n c a o p u b l i c O b j e c t [ ] [ ] . . . . Type ] . . . . . ReferenceType [ ] [ ] . . . . . . ClassOrInterfaceType Class : : Object ( , ) . . . . ParameterList a . . . . . Parameter V a r i a b l e : : a " n u l l " . . . . . . Type i n t . . . . . . . BasicType i n t . . . . . . Variable Variable : : a " null " . . . . CompoundStatement } xxxviii Luís Laranjeira - PJMAS Resultado do Teste: Pass. Resolução do Problema: No exemplo anterior não estava a ser preenchida corretamente a AST, o autor estava a identificar todos os “Tokens” corretamente, no entanto no momento de preenchimento da AST não estava a colocar os valores obtidos com o nó “Type”. Após o preenchimento com os valores obtidos passou com sucesso no teste. xxxix Luís Laranjeira - PJMAS ID Teste: 10 Data: 26/03/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Variáveis/objetos e funções. Descrição: Ficheiro Teste.java, com declaração de variáveis e funções com e sem retorno de objetos. Conteúdo do ficheiro de input: p u b l i c c l a s s Teste { p r i v a t e i n t v a r i a v e l =20; } public String funcao ( i n t a ) { f i n a l i n t v=v a r i a v e l ; int i ; i=v a r i a v e l ++; S t r i n g s t r i n g=f u n c a o ( i ) ; return null ; } Resultado Parsing Esperado: Parsing sem qualquer erro e árvore obtida preenchida corretamente. Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado: ASTRoot . N o r m a l C l a s s D e c l a r a t i o n C l a s s : : Teste ( , ) . . ClassMembers } . . . MemberDeclaration ; . . . . V a r i a b l e D e c l a r a t i o n 20 . . . . . Type i n t . . . . . . BasicType i n t . . . . . Variable2 Variable : : integer : : v a r i a v e l private " null " . . . . . . Constant Constant : : i n t : : 2 0 . . . MemberDeclaration F u n c t i o n : : f u n c a o p u b l i c S t r i n g . . . . Type S t r i n g . . . . . ReferenceType S t r i n g . . . . . . ClassOrInterfaceType Class : : String ( , ) . . . . ParameterList a . . . . . Parameter V a r i a b l e : : i n t e g e r : : a " n u l l " . . . . . . Type i n t . . . . . . . BasicType i n t . . . . . . Variable Variable : : integer : : a " null " . . . . CompoundStatement } . . . . . Statement ; . . . . . . ExpressionStatement v a r i a v e l . . . . . . . VariableDeclaration variavel . . . . . . . . Type i n t . . . . . . . . . BasicType i n t . . . . . . . . Variable2 Variable : : integer : : v f i n a l " null " . . . . . . . . . Variable Variable : : variavel " null " . . . . . Statement ; . . . . . . ExpressionStatement i . . . . . . . VariableDeclaration i xl Luís Laranjeira - PJMAS . . . . . . . . Type i n t . . . . . . . . . BasicType i n t . . . . . . . . Variable2 Variable : : integer : : i " null " . . . . . Statement ; . . . . . . E x p r e s s i o n S t a t e m e n t ++ . . . . . . . A s s i g n m e n t E x p r e s s i o n ++ . . . . . . . . Variable Variable : : i " null " . . . . . . . . AssignmentOperator Operator : : = . . . . . . . . P o s t f i x I n c D e c E x p r e s s i o n Operator ::++ . . . . . . . . . Variable Variable : : variavel " null " . . . . . Statement ; . . . . . . ExpressionStatement ) . . . . . . . VariableDeclaration ) . . . . . . . . Type S t r i n g . . . . . . . . . ReferenceType S t r i n g . . . . . . . . . . ClassOrInterfaceType Class : : String ( , ) . . . . . . . . Variable2 Variable : : s tr i ng : : s tr i n g " null " . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . Variable Variable : : funcao " n u l l " . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . Variable Variable : : i " null " . . . . . Statement ; . . . . . . JumpStatement JumpStatement : : r e t u r n . . . . . . . Constant Constant : : p r e d e f i n e d : : n u l l Resultado do Teste: Pass. xli Luís Laranjeira - PJMAS ID Teste: 11 Data: 29/03/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Variáveis/objetos, funções e condições. Descrição: Ficheiro Teste.java, com declaração de variáveis, funções com e sem retorno de objetos, condições if-else com várias combinações e switch-case. Conteúdo do ficheiro de input: p u b l i c c l a s s Teste { private int variavel = 20; static { String a = " teste " ; System . out . p r i n t ( " ddd " + a ) ; } p u b l i c Teste ( i n t v a r i a v e l ) { super ( ) ; this . variavel = variavel ; funcao ( v a r i a v e l ) ; } p r i v a t e v o i d f u n c a o P r i ( A r r a y L i s t <S t r i n g > a , S t r i n g op , S t r i n g n ) { int l = a . size ( ) ; i f ( a . isEmpty ( ) ) return ; e l s e i f ( ! op . endsWith ( " . j a v a " ) && op . l e n g t h ( ) > 2 | | n . c o n t a i n s ( " t " ) ) { return ; } s w i t c h ( op ) { case " a " : a . add ( n ) ; break ; case " b " : a . add ( " b " ) ; break ; case " c " : a . remove ( n ) ; break ; default : System . out . p r i n t l n ( " i n v a l i d " ) ; break ; } } public String funcao ( i n t a ) { i f ( a < 0) r e t u r n " no " ; e l s e i f ( a == 0 ) return " true " ; else r e t u r n " nop " ; } public i n t getVariavel ( ) { return variavel ; } public void s et V ar i av e l ( i n t v a r i a v e l ) { this . variavel = variavel ; } } Resultado Parsing Esperado: Parsing sem qualquer erro e árvore obtida preenchida corretamente. xlii Luís Laranjeira - PJMAS Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado: ASTRoot . N o r m a l C l a s s D e c l a r a t i o n C l a s s : : Teste ( , ) . . ClassMembers } . . . MemberDeclaration ; . . . . V a r i a b l e D e c l a r a t i o n 20 . . . . . Type i n t . . . . . . BasicType i n t . . . . . Variable2 Variable : : integer : : v a r i a v e l private " null " . . . . . . Constant Constant : : i n t : : 2 0 . . . MemberDeclaration } . . . . CompoundStatement } . . . . . Statement ; . . . . . . ExpressionStatement " t e s t e " . . . . . . . VariableDeclaration " teste " . . . . . . . . Type S t r i n g . . . . . . . . . ReferenceType S t r i n g . . . . . . . . . . ClassOrInterfaceType Class : : String ( , ) . . . . . . . . Variable2 Variable : : s tr i ng : : a " null " . . . . . . . . . Constant Constant : : s t r i n g : : " t e s t e " . . . . . Statement ; . . . . . . ExpressionStatement ) . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . V a r i a b l e V a r i a b l e : : System " n u l l " . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . V a r i a b l e V a r i a b l e : : out " n u l l " . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . Variable Variable : : print " null " . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . AdditiveExpression + . . . . . . . . . . . . Constant Constant : : s t r i n g : : " ddd " . . . . . . . . . . . . Variable Variable : : a " null " . . . MemberDeclaration F u n c t i o n : : Teste p u b l i c . . . . ParameterList v a r i a v e l . . . . . Parameter V a r i a b l e : : i n t e g e r : : v a r i a v e l " n u l l " . . . . . . Type i n t . . . . . . . BasicType i n t . . . . . . Variable Variable : : integer : : variavel " null " . . . . CompoundStatement } . . . . . Statement ; . . . . . . ExpressionStatement ) . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . ArgumentExpressionList ) . . . . . Statement ; . . . . . . ExpressionStatement v a r i a v e l . . . . . . . AssignmentExpression v a r i a v e l . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . Constant Constant : : p r e d e f i n e d : : t h i s . . . . . . . . . Variable Variable : : variavel " null " . . . . . . . . AssignmentOperator Operator : : = . . . . . . . . Variable Variable : : variavel " null " . . . . . Statement ; . . . . . . ExpressionStatement ) . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . Variable Variable : : funcao " n u l l " . . . . . . . . ArgumentExpressionList ) xliii Luís Laranjeira - PJMAS . . . . . . . . . Variable Variable : : variavel " null " . . . MemberDeclaration F u n c t i o n : : f u n c a o P r i p r i v a t e v o i d . . . . ParameterList n . . . . . Parameter V a r i a b l e : : o b j e c t : : a " C l a s s : : A r r a y L i s t <S t r i n g > ( , ) " . . . . . . Type > . . . . . . . ReferenceType > . . . . . . . . C l a s s O r I n t e r f a c e T y p e C l a s s : : A r r a y L i s t <S t r i n g > ( , ) . . . . . . . . . TypeArguments <S t r i n g > . . . . . . . . . . TypeArgument S t r i n g . . . . . . . . . . . ReferenceType S t r i n g . . . . . . . . . . . . ClassOrInterfaceType Class : : String ( , ) . . . . . . V a r i a b l e V a r i a b l e : : o b j e c t : : a " C l a s s : : A r r a y L i s t <S t r i n g > ( , ) " . . . . . Parameter V a r i a b l e : : s t r i n g : : op " n u l l " . . . . . . Type S t r i n g . . . . . . . ReferenceType S t r i n g . . . . . . . . ClassOrInterfaceType Class : : String ( , ) . . . . . . V a r i a b l e V a r i a b l e : : s t r i n g : : op " n u l l " . . . . . Parameter V a r i a b l e : : s t r i n g : : n " n u l l " . . . . . . Type S t r i n g . . . . . . . ReferenceType S t r i n g . . . . . . . . ClassOrInterfaceType Class : : String ( , ) . . . . . . Variable Variable : : string : : n " null " . . . . CompoundStatement } . . . . . Statement ; . . . . . . ExpressionStatement ) . . . . . . . VariableDeclaration ) . . . . . . . . Type i n t . . . . . . . . . BasicType i n t . . . . . . . . Variable2 Variable : : integer : : l " null " . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . Variable Variable : : a " null " . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . Variable Variable : : size " null " . . . . . . . . . . . ArgumentExpressionList ) . . . . . Statement } . . . . . . SelectionStatement I f _ e l s e i f _ e l s e . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . Variable Variable : : a " null " . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . V a r i a b l e V a r i a b l e : : isEmpty " n u l l " . . . . . . . . . ArgumentExpressionList ) . . . . . . . Statement ; . . . . . . . . JumpStatement JumpStatement : : r e t u r n . . . . . . . Statement } . . . . . . . . SelectionStatement I f _ e l s e i f _ e l s e . . . . . . . . . Logical_Or_Expression ) . . . . . . . . . . Logical_And_Expression 2 . . . . . . . . . . . UnaryExpression Operator : : ! . . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : op " n u l l " . . . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : endsWith " n u l l " . . . . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . . . . . Constant Constant : : s t r i n g : : " . j a v a " . . . . . . . . . . . RelationalExpression > . . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : op " n u l l " . . . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . . . Variable Variable : : length " null " . . . . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . . Constant Constant : : i n t : : 2 . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> xliv Luís Laranjeira - PJMAS . . . . . . . . . . . Variable Variable : : n " null " . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . Variable Variable : : contains " null " . . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . . . Constant Constant : : s t r i n g : : " t " . . . . . . . . . Statement } . . . . . . . . . . CompoundStatement } . . . . . . . . . . . Statement ; . . . . . . . . . . . . JumpStatement JumpStatement : : r e t u r n . . . . . Statement } . . . . . . S e l e c t i o n S t a t e m e n t Switch . . . . . . . V a r i a b l e V a r i a b l e : : op " n u l l " . . . . . . . Statement } . . . . . . . . CompoundStatement } . . . . . . . . . Statement ; . . . . . . . . . . LabeledStatement LabeledStatement : : case . . . . . . . . . . . Constant Constant : : s t r i n g : : " a " . . . . . . . . . . . Statement ; . . . . . . . . . . . . ExpressionStatement ) . . . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . . . Variable Variable : : a " null " . . . . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : add " n u l l " . . . . . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . . . . . . Variable Variable : : n " null " . . . . . . . . . . . Statement ; . . . . . . . . . . . . JumpStatement JumpStatement : : break . . . . . . . . . . . Statement ; . . . . . . . . . . . . LabeledStatement LabeledStatement : : case . . . . . . . . . . . . . Constant Constant : : s t r i n g : : " b " . . . . . . . . . . . . . Statement ; . . . . . . . . . . . . . . ExpressionStatement ) . . . . . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . . . . . Variable Variable : : a " null " . . . . . . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : add " n u l l " . . . . . . . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . . . . . . . . Constant Constant : : s t r i n g : : " b " . . . . . . . . . . . . . Statement ; . . . . . . . . . . . . . . JumpStatement JumpStatement : : break . . . . . . . . . . . . . Statement ; . . . . . . . . . . . . . . LabeledStatement LabeledStatement : : case . . . . . . . . . . . . . . . Constant Constant : : s t r i n g : : " c " . . . . . . . . . . . . . . . Statement ; . . . . . . . . . . . . . . . . ExpressionStatement ) . . . . . . . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . . . . . . . Variable Variable : : a " null " . . . . . . . . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : remove " n u l l " . . . . . . . . . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . . . . . . . . . . Variable Variable : : n " null " . . . . . . . . . . . . . . . Statement ; . . . . . . . . . . . . . . . . JumpStatement JumpStatement : : break . . . . . . . . . . . . . . . Statement ; . . . . . . . . . . . . . . . . LabeledStatement LabeledStatement : : d e f a u l t . . . . . . . . . . . . . . . . . Statement ; . . . . . . . . . . . . . . . . . . ExpressionStatement ) . . . . . . . . . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : System " n u l l " . . . . . . . . . . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : out " n u l l " . . . . . . . . . . . . . . . . . . . . . PostfixExpression PostfixExpression : : ( xlv Luís Laranjeira - PJMAS . . . . . . . . . . . . . . . . . . . . . . Variable Variable : : p r i n t l n " null " . . . . . . . . . . . . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . . . . . . . . . . . . . Constant Constant : : s t r i n g : : " i n v a l i d " . . . . . . . . . . . . . . . . . Statement ; . . . . . . . . . . . . . . . . . . JumpStatement JumpStatement : : break . . . MemberDeclaration F u n c t i o n : : f u n c a o p u b l i c S t r i n g . . . . Type S t r i n g . . . . . ReferenceType S t r i n g . . . . . . ClassOrInterfaceType Class : : String ( , ) . . . . ParameterList a . . . . . Parameter V a r i a b l e : : i n t e g e r : : a " n u l l " . . . . . . Type i n t . . . . . . . BasicType i n t . . . . . . Variable Variable : : integer : : a " null " . . . . CompoundStatement } . . . . . Statement ; . . . . . . SelectionStatement I f _ e l s e i f _ e l s e . . . . . . . RelationalExpression < . . . . . . . . Variable Variable : : a " null " . . . . . . . . Constant Constant : : i n t : : 0 . . . . . . . Statement ; . . . . . . . . JumpStatement JumpStatement : : r e t u r n . . . . . . . . . Constant Constant : : s t r i n g : : " no " . . . . . . . Statement ; . . . . . . . . SelectionStatement I f _ e l s e i f _ e l s e . . . . . . . . . E q u a l i t y E x p r e s s i o n == . . . . . . . . . . Variable Variable : : a " null " . . . . . . . . . . Constant Constant : : i n t : : 0 . . . . . . . . . Statement ; . . . . . . . . . . JumpStatement JumpStatement : : r e t u r n . . . . . . . . . . . Constant Constant : : s t r i n g : : " t r u e " . . . . . . . . . Statement ; . . . . . . . . . . JumpStatement JumpStatement : : r e t u r n . . . . . . . . . . . Constant Constant : : s t r i n g : : " nop " . . . MemberDeclaration F u n c t i o n : : g e t V a r i a v e l p u b l i c i n t e g e r . . . . Type i n t . . . . . BasicType i n t . . . . CompoundStatement } . . . . . Statement ; . . . . . . JumpStatement JumpStatement : : r e t u r n . . . . . . . Variable Variable : : variavel " null " . . . MemberDeclaration F u n c t i o n : : s e t V a r i a v e l p u b l i c v o i d . . . . ParameterList v a r i a v e l . . . . . Parameter V a r i a b l e : : i n t e g e r : : v a r i a v e l " n u l l " . . . . . . Type i n t . . . . . . . BasicType i n t . . . . . . Variable Variable : : integer : : variavel " null " . . . . CompoundStatement } . . . . . Statement ; . . . . . . ExpressionStatement v a r i a v e l . . . . . . . AssignmentExpression v a r i a v e l . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . Constant Constant : : p r e d e f i n e d : : t h i s . . . . . . . . . Variable Variable : : variavel " null " . . . . . . . . AssignmentOperator Operator : : = . . . . . . . . Variable Variable : : variavel " null " Resultado do Teste: Pass. xlvi Luís Laranjeira - PJMAS ID Teste: 12 Data: 02/04/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Iterações. Descrição: Ficheiro Teste.java, com vários ciclos diferentes. Conteúdo do ficheiro de input: (...) f o r ( i n t i =0; i <10; i ++){ i +=0; } i n t j =10; while ( j >0){ j −=1; } do{ i n t i =1; j=j+i ; } while ( j <10) ; (...) Resultado Parsing Esperado: Parsing sem qualquer erro e árvore obtida preenchida corretamente. Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado: (...) . . . . . Statement } . . . . . . IterationStatement IterationStatement : : for . . . . . . . VariableDeclaration 0 . . . . . . . . Type i n t . . . . . . . . . BasicType i n t . . . . . . . . Variable2 Variable : : integer : : i " null " . . . . . . . . . Constant Constant : : i n t : : 0 . . . . . . . RelationalExpression < . . . . . . . . Variable Variable : : i " null " . . . . . . . . Constant Constant : : i n t : : 1 0 . . . . . . . P o s t f i x I n c D e c E x p r e s s i o n Operator ::++ . . . . . . . . Variable Variable : : i " null " . . . . . . . Statement } . . . . . . . . CompoundStatement } . . . . . . . . . Statement ; . . . . . . . . . . ExpressionStatement 0 . . . . . . . . . . . AssignmentExpression 0 . . . . . . . . . . . . Variable Variable : : i " null " . . . . . . . . . . . . AssignmentOperator Operator ::+= . . . . . . . . . . . . Constant Constant : : i n t : : 0 . . . . . Statement ; . . . . . . E x p r e s s i o n S t a t e m e n t 10 . . . . . . . V a r i a b l e D e c l a r a t i o n 10 . . . . . . . . Type i n t . . . . . . . . . BasicType i n t . . . . . . . . Variable2 Variable : : integer : : j " null " xlvii Luís Laranjeira - PJMAS . . . . . . . . . Constant Constant : : i n t : : 1 0 . . . . . Statement } . . . . . . IterationStatement IterationStatement : : while . . . . . . . RelationalExpression > . . . . . . . . Variable Variable : : j " null " . . . . . . . . Constant Constant : : i n t : : 0 . . . . . . . Statement } . . . . . . . . CompoundStatement } . . . . . . . . . Statement ; . . . . . . . . . . ExpressionStatement 1 . . . . . . . . . . . AssignmentExpression 1 . . . . . . . . . . . . Variable Variable : : j " null " . . . . . . . . . . . . AssignmentOperator Operator ::−= . . . . . . . . . . . . Constant Constant : : i n t : : 1 . . . . . Statement ; . . . . . . I t e r a t i o n S t a t e m e n t I t e r a t i o n S t a t e m e n t : : do_while . . . . . . . Statement } . . . . . . . . CompoundStatement } . . . . . . . . . Statement ; . . . . . . . . . . ExpressionStatement 1 . . . . . . . . . . . VariableDeclaration 1 . . . . . . . . . . . . Type i n t . . . . . . . . . . . . . BasicType i n t . . . . . . . . . . . . Variable2 Variable : : integer : : i " null " . . . . . . . . . . . . . Constant Constant : : i n t : : 1 . . . . . . . . . Statement ; . . . . . . . . . . ExpressionStatement i . . . . . . . . . . . AssignmentExpression i . . . . . . . . . . . . Variable Variable : : j " null " . . . . . . . . . . . . AssignmentOperator Operator : : = . . . . . . . . . . . . AdditiveExpression + . . . . . . . . . . . . . Variable Variable : : j " null " . . . . . . . . . . . . . Variable Variable : : i " null " . . . . . . . RelationalExpression < . . . . . . . . Variable Variable : : j " null " . . . . . . . . Constant Constant : : i n t : : 1 0 (...) Resultado do Teste: Pass. xlviii Luís Laranjeira - PJMAS ID Teste: 13 Data: 03/04/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Iterações. Descrição: Ficheiro Teste.java, com ciclos “for” diferentes. Conteúdo do ficheiro de input: (...) S t r i n g a=" . d f s f " ; f o r ( i n t k =0;k<10 && a . l e n g t h ( ) >2;) { k=a . l e n g t h ( ) ; } f o r ( S t r i n g it e m : l i s t ) { System . out . p r i n t l n ( it e m ) ; } (...) Resultado Parsing Esperado: Parsing sem qualquer erro e árvore obtida preenchida corretamente. Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado: (...) . . . . . Statement ; . . . . . . ExpressionStatement " . d f s f " . . . . . . . VariableDeclaration " . d f s f " . . . . . . . . Type S t r i n g . . . . . . . . . ReferenceType S t r i n g . . . . . . . . . . ClassOrInterfaceType Class : : String ( , ) . . . . . . . . Variable2 Variable : : s tr i ng : : a " null " . . . . . . . . . Constant Constant : : s t r i n g : : " . d f s f " . . . . . Statement } . . . . . . IterationStatement IterationStatement : : for . . . . . . . VariableDeclaration 0 . . . . . . . . Type i n t . . . . . . . . . BasicType i n t . . . . . . . . Variable2 Variable : : integer : : k " null " . . . . . . . . . Constant Constant : : i n t : : 0 . . . . . . . Logical_And_Expression 2 . . . . . . . . RelationalExpression < . . . . . . . . . Variable Variable : : k " null " . . . . . . . . . Constant Constant : : i n t : : 1 0 . . . . . . . . RelationalExpression > . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . Variable Variable : : a " null " . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . Variable Variable : : length " null " . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . Constant Constant : : i n t : : 2 . . . . . . . Statement } . . . . . . . . CompoundStatement } . . . . . . . . . Statement ; . . . . . . . . . . ExpressionStatement ) xlix Luís Laranjeira - PJMAS . . . . . . . . . . . AssignmentExpression ) . . . . . . . . . . . . Variable Variable : : k " null " . . . . . . . . . . . . AssignmentOperator Operator : : = . . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . . Variable Variable : : a " null " . . . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . . . Variable Variable : : length " null " . . . . . . . . . . . . . . ArgumentExpressionList ) . . . . . Statement } . . . . . . IterationStatement IterationStatement : : foreach . . . . . . . V a r i a b l e D e c l a r a t i o n i te m . . . . . . . . Type S t r i n g . . . . . . . . . ReferenceType S t r i n g . . . . . . . . . . ClassOrInterfaceType Class : : String ( , ) . . . . . . . . V a r i a b l e 2 V a r i a b l e : : s t r i n g : : it e m " n u l l " . . . . . . . Variable Variable : : l i s t " null " . . . . . . . Statement } . . . . . . . . CompoundStatement } . . . . . . . . . Statement ; . . . . . . . . . . ExpressionStatement ) . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : System " n u l l " . . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : out " n u l l " . . . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . . . Variable Variable : : p r i n t l n " null " . . . . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : i te m " n u l l " (...) Resultado do Teste: Pass. l Luís Laranjeira - PJMAS ID Teste: 14 Data: 05/04/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Try-Catch. Descrição: Ficheiro Teste.java, com um Try-Catch-Finally. Conteúdo do ficheiro de input: (...) try { F i l e I n p u t S t r e a m f = new F i l e I n p u t S t r e a m ( " i n . t x t " ) ; i f ( f . a v a i l a b l e ( ) >0) { return ; } } c a t c h ( FileNotFoundException e ) { e . printStackTrace ( ) ; } catch ( IOException e ) { e . printStackTrace ( ) ; } finally { System . out . p r i n t l n ( MethodType . make ( v o i d . c l a s s , S t r i n g . c l a s s ) ) ; } (...) Resultado Parsing Esperado: Parsing sem qualquer erro e árvore obtida preenchida corretamente. Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado: (...) . . . . CompoundStatement } . . . . . Statement } . . . . . . TryStatement } . . . . . . . CompoundStatement } . . . . . . . . Statement ; . . . . . . . . . ExpressionStatement ) . . . . . . . . . . VariableDeclaration ) . . . . . . . . . . . Type F i l e I n p u t S t r e a m . . . . . . . . . . . . ReferenceType F i l e I n p u t S t r e a m . . . . . . . . . . . . . ClassOrInterfaceType Class : : FileInputStream ( , ) . . . . . . . . . . . Variable2 Variable : : o b j e c t : : f " Class : : FileInputStream ( , ) " . . . . . . . . . . . . ClassInstantiation ) . . . . . . . . . . . . . Type F i l e I n p u t S t r e a m . . . . . . . . . . . . . . ReferenceType F i l e I n p u t S t r e a m . . . . . . . . . . . . . . . ClassOrInterfaceType Class : : FileInputStream ( , ) . . . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . . . . Constant Constant : : s t r i n g : : " i n . t x t " . . . . . . . . Statement } . . . . . . . . . SelectionStatement I f _ e l s e i f _ e l s e . . . . . . . . . . RelationalExpression > . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . Variable Variable : : f " null " . . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . . Variable Variable : : available " null " . . . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . Constant Constant : : i n t : : 0 li Luís Laranjeira - PJMAS . . . . . . . . . . Statement } . . . . . . . . . . . CompoundStatement } . . . . . . . . . . . . Statement ; . . . . . . . . . . . . . JumpStatement JumpStatement : : r e t u r n . . . . . . . CatchClause [ ] . . . . . . . . V a r i a b l e V a r i a b l e : : o b j e c t : : e " C l a s s : : FileNotFoundException ( , ) " . . . . . . . . CompoundStatement } . . . . . . . . . Statement ; . . . . . . . . . . ExpressionStatement ) . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . Variable Variable : : e " null " . . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . . Variable Variable : : printStackTrace " null " . . . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . CatchClause [ ] . . . . . . . . Variable Variable : : o b j e c t : : e " Class : : IOException ( , ) " . . . . . . . . CompoundStatement } . . . . . . . . . Statement ; . . . . . . . . . . ExpressionStatement ) . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . Variable Variable : : e " null " . . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . . Variable Variable : : printStackTrace " null " . . . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . Finally } . . . . . . . . CompoundStatement } . . . . . . . . . Statement ; . . . . . . . . . . ExpressionStatement ) . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : System " n u l l " . . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : out " n u l l " . . . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . . . Variable Variable : : p r i n t l n " null " . . . . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : MethodType " n u l l " . . . . . . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : make " n u l l " . . . . . . . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . . . . . . . . Variable Variable : : String " null " (...) Resultado do Teste: Pass. lii Luís Laranjeira - PJMAS ID Teste: 15 Data: 10/04/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Classe @Interface (anotações). Descrição: Ficheiro Foo.java, com várias declarações de anotações. Conteúdo do ficheiro de input: (...) p u b l i c @ i n t e r f a c e Foo { int id ( ) ; String synopsis ( ) ; S t r i n g e n g i n e e r ( ) d e f a u l t " [ unassigned ] " ; S t r i n g date ( ) d e f a u l t " [ unimplemented ] " ; @Target ( ElementType . TYPE ) @Retention ( R e t e n t i o n P o l i c y . RUNTIME) p u b l i c @ i n t e r f a c e TypeAnnotation { } } @Target ( ElementType . FIELD ) @Retention ( R e t e n t i o n P o l i c y . RUNTIME) public @interface FieldAnnotation { } @Target ( ElementType .METHOD) @Retention ( R e t e n t i o n P o l i c y . RUNTIME) p u b l i c @ i n t e r f a c e MethodAnnotation { } @Target ( ElementType . PARAMETER) @Retention ( R e t e n t i o n P o l i c y . RUNTIME) p u b l i c @ i n t e r f a c e ParameterAnnotation { } Resultado Parsing Esperado: Parsing sem qualquer erro e árvore obtida preenchida corretamente. Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado: (...) . A n n o t a t i o n T y p e D e c l a r a t i o n A n n o t a t i o n : : Foo . . AnnotationTypeBody } . . . AnnotationBodyDeclaration ; . . . . AnnotationMathodRest ) . . . . . Type i n t . . . . . . BasicType i n t . . . AnnotationBodyDeclaration ; . . . . AnnotationMathodRest ) . . . . . Type S t r i n g . . . . . . ReferenceType S t r i n g . . . . . . . ClassOrInterfaceType Class : : String ( , ) . . . AnnotationBodyDeclaration ; . . . . AnnotationMathodRest " [ unassigned ] " . . . . . Type S t r i n g . . . . . . ReferenceType S t r i n g . . . . . . . ClassOrInterfaceType Class : : String ( , ) . . . . . Constant Constant : : s t r i n g : : " [ unassigned ] " liii Luís Laranjeira - PJMAS . . . AnnotationBodyDeclaration ; . . . . AnnotationMathodRest " [ unimplemented ] " . . . . . Type S t r i n g . . . . . . ReferenceType S t r i n g . . . . . . . ClassOrInterfaceType Class : : String ( , ) . . . . . Constant Constant : : s t r i n g : : " [ unimplemented ] " . . . AnnotationBodyDeclaration } . . . . A n n o t a t i o n A n n o t a t i o n : : Target . . . . . ArgumentExpressionList ) . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . V a r i a b l e V a r i a b l e : : ElementType " n u l l " . . . . . . . V a r i a b l e V a r i a b l e : : TYPE " n u l l " . . . . Annotation Annotation : : Retention . . . . . ArgumentExpressionList ) . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . Variable Variable : : RetentionPolicy " null " . . . . . . . V a r i a b l e V a r i a b l e : : RUNTIME " n u l l " . . . . A n n o t a t i o n T y p e D e c l a r a t i o n A n n o t a t i o n : : TypeAnnotation . . . . . AnnotationTypeBody } . . . AnnotationBodyDeclaration } . . . . A n n o t a t i o n A n n o t a t i o n : : Target . . . . . ArgumentExpressionList ) . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . V a r i a b l e V a r i a b l e : : ElementType " n u l l " . . . . . . . V a r i a b l e V a r i a b l e : : FIELD " n u l l " . . . . Annotation Annotation : : Retention . . . . . ArgumentExpressionList ) . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . Variable Variable : : RetentionPolicy " null " . . . . . . . V a r i a b l e V a r i a b l e : : RUNTIME " n u l l " . . . . AnnotationTypeDeclaration Annotation : : FieldAnnotation . . . . . AnnotationTypeBody } . . . AnnotationBodyDeclaration } . . . . A n n o t a t i o n A n n o t a t i o n : : Target . . . . . ArgumentExpressionList ) . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . V a r i a b l e V a r i a b l e : : ElementType " n u l l " . . . . . . . V a r i a b l e V a r i a b l e : : METHOD " n u l l " . . . . Annotation Annotation : : Retention . . . . . ArgumentExpressionList ) . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . Variable Variable : : RetentionPolicy " null " . . . . . . . V a r i a b l e V a r i a b l e : : RUNTIME " n u l l " . . . . A n n o t a t i o n T y p e D e c l a r a t i o n A n n o t a t i o n : : MethodAnnotation . . . . . AnnotationTypeBody } . . . AnnotationBodyDeclaration } . . . . A n n o t a t i o n A n n o t a t i o n : : Target . . . . . ArgumentExpressionList ) . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . V a r i a b l e V a r i a b l e : : ElementType " n u l l " . . . . . . . V a r i a b l e V a r i a b l e : : PARAMETER " n u l l " . . . . Annotation Annotation : : Retention . . . . . ArgumentExpressionList ) . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . Variable Variable : : RetentionPolicy " null " . . . . . . . V a r i a b l e V a r i a b l e : : RUNTIME " n u l l " . . . . A n n o t a t i o n T y p e D e c l a r a t i o n A n n o t a t i o n : : ParameterAnnotation . . . . . AnnotationTypeBody } Resultado do Teste: Pass. liv Luís Laranjeira - PJMAS ID Teste: 16 Data: 10/04/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Classe @Interface (anotações) e anotações em métodos e/ou variáveis. Descrição: Ficheiro Connector.java, com declaração de uma anotação e uso de várias anotações no código. Conteúdo do ficheiro de input: (...) @Retention ( R e t e n t i o n P o l i c y . RUNTIME) @ i n t e r f a c e MyAnno { String str ( ) ; int val ( ) ; } @WebService p u b l i c c l a s s Connector { @WebMethod p u b l i c S t r i n g getUsers ( @WebParam ( name = " company " ) S t r i n g company ) { } } @MyAnno ( s t r = " A n n o t a t i o n Example " , v a l = 1 0 0 ) private void funcao ( String [ ] l i s t ) { } Resultado Parsing Esperado: Parsing sem qualquer erro e árvore obtida preenchida corretamente. Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado: (...) . Annotation Annotation : : Retention . . ArgumentExpressionList ) . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . Variable Variable : : RetentionPolicy " null " . . . . V a r i a b l e V a r i a b l e : : RUNTIME " n u l l " . A n n o t a t i o n T y p e D e c l a r a t i o n A n n o t a t i o n : : MyAnno . . AnnotationTypeBody } . . . AnnotationBodyDeclaration ; . . . . AnnotationMathodRest ) . . . . . Type S t r i n g . . . . . . ReferenceType S t r i n g . . . . . . . ClassOrInterfaceType Class : : String ( , ) . . . AnnotationBodyDeclaration ; . . . . AnnotationMathodRest ) . . . . . Type i n t . . . . . . BasicType i n t . A n n o t a t i o n A n n o t a t i o n : : WebService . N o r m a l C l a s s D e c l a r a t i o n C l a s s : : Connector ( , ) . . ClassMembers } . . . MemberDeclaration F u n c t i o n : : getUsers p u b l i c S t r i n g lv Luís Laranjeira - PJMAS . . . . A n n o t a t i o n A n n o t a t i o n : : WebMethod . . . . Type S t r i n g . . . . . ReferenceType S t r i n g . . . . . . ClassOrInterfaceType Class : : String ( , ) . . . . P a r a m e t e r L i s t company . . . . . Parameter V a r i a b l e : : s t r i n g : : company " n u l l " . . . . . . A n n o t a t i o n A n n o t a t i o n : : WebParam . . . . . . . ArgumentExpressionList ) . . . . . . . . A s s i g n m e n t E x p r e s s i o n " company " . . . . . . . . . V a r i a b l e V a r i a b l e : : name " n u l l " . . . . . . . . . AssignmentOperator Operator : : = . . . . . . . . . Constant Constant : : s t r i n g : : " company " . . . . . . Type S t r i n g . . . . . . . ReferenceType S t r i n g . . . . . . . . ClassOrInterfaceType Class : : String ( , ) . . . . . . V a r i a b l e V a r i a b l e : : s t r i n g : : company " n u l l " . . . . CompoundStatement } . . . MemberDeclaration F u n c t i o n : : f u n c a o p r i v a t e v o i d . . . . A n n o t a t i o n A n n o t a t i o n : : MyAnno . . . . . ArgumentExpressionList ) . . . . . . A s s i g n m e n t E x p r e s s i o n " A n n o t a t i o n Example " . . . . . . . Variable Variable : : str " null " . . . . . . . AssignmentOperator Operator : : = . . . . . . . Constant Constant : : s t r i n g : : " A n n o t a t i o n Example " . . . . . . A s s i g n m e n t E x p r e s s i o n 100 . . . . . . . Variable Variable : : val " null " . . . . . . . AssignmentOperator Operator : : = . . . . . . . Constant Constant : : i n t : : 1 0 0 . . . . ParameterList l i s t . . . . . Parameter V a r i a b l e : : a r r a y : : l i s t " A r r a y V a r i a b l e <C l a s s : : S t r i n g ( , )> [ ] " . . . . . . Type ] . . . . . . . ReferenceType [ ] . . . . . . . . ClassOrInterfaceType Class : : String ( , ) . . . . . . V a r i a b l e V a r i a b l e : : a r r a y : : l i s t " A r r a y V a r i a b l e <C l a s s : : S t r i n g ( , )> [ ] " . . . . CompoundStatement } Resultado do Teste: Pass. lvi Luís Laranjeira - PJMAS G.1.2 Testes às JSP ID Teste: 17 Data: 17/04/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Deteção de HTML e de comentários em JSP. Descrição: Ficheiro teste.jsp, com comentário em JSP e vários pedaços de HTML. Conteúdo do ficheiro de input: <!DOCTYPE html PUBLIC " −//W3C / / DTD HTML 4 . 0 1 T r a n s i t i o n a l / /EN" " h t t p : / / www. w3 . org / TR / html4 / l o o s e . dtd "> <html> <head> <meta h t t p−e q u i v=" Content−Type " c o n t e n t=" t e x t / html ; c h a r s e t=UTF−8 "> < t i t l e >T i t u l o </ t i t l e > </head> <body> <%−− Comentá r i o . . . . . . . . . . . . . S t r i n g i d= r e q u e s t . getParameter ( " i d " ) ; −−%> </body> </ html> Resultado Parsing Esperado: Parsing sem qualquer erro e árvore obtida preenchida corretamente. Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado: ASTRoot . JspPage DOCTYPE html PUBLIC " − / /W3C / / D ( . . . ) i t u l o . . HtmlBlock HtmlBlock : : < !DOCTYPE html PUBL ( . . . ) i t u l o . . . JspCheck <!DOCTYPE html PUBLIC " − / /W3C/ ( . . . ) itulo . JspPage t i t l e > . . HtmlBlock HtmlBlock : : < / t i t l e > . JspPage head> <body> . . HtmlBlock HtmlBlock : : < / head> <body> . JspPage −−%> . . JspComment −−%> . JspPage . . HtmlBlock HtmlBlock : : . JspPage body> . . HtmlBlock HtmlBlock : : < / body> . JspPage html> . . HtmlBlock HtmlBlock : : < / html> Resultado do Teste: Pass. lvii Luís Laranjeira - PJMAS ID Teste: 18 Data: 20/04/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Deteção Scriptlets, no formato XML e JSP, e do código Java no seu interior. Descrição: Ficheiro teste.jsp, código Java usando Scriptlets. Conteúdo do ficheiro de input: (...) <body> <% S t r i n g i d= r e q u e s t . getParameter ( " i d " ) ; f o r ( i n t i =0; i <10; i ++){ i t e r a c a o aqui . . . <j s p : s c r i p t l e t > out . p r i n t l n ( i d ) ; } </ j s p : s c r i p t l e t > </body> (...) %> Resultado Parsing Esperado: Parsing sem qualquer erro e árvore obtida preenchida corretamente. Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado: (...) . JspPage head> <body> . . HtmlBlock HtmlBlock : : < / head> <body> . JspPage </ j s p : s c r i p t l e t > . . Statement ; . . . ExpressionStatement ) . . . . VariableDeclaration ) . . . . . Type S t r i n g . . . . . . ReferenceType S t r i n g . . . . . . . ClassOrInterfaceType Class : : String ( , ) . . . . . Variable2 Variable : : s t ri n g : : id " null " . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . Variable Variable : : request " n u l l " . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . V a r i a b l e V a r i a b l e : : getParameter " n u l l " . . . . . . . . ArgumentExpressionList ) . . . . . . . . . Constant Constant : : s t r i n g : : " i d " . . Statement } . . . IterationStatement IterationStatement : : for . . . . VariableDeclaration 0 . . . . . Type i n t . . . . . . BasicType i n t . . . . . Variable2 Variable : : integer : : i " null " . . . . . . Constant Constant : : i n t : : 0 . . . . RelationalExpression < . . . . . Variable Variable : : i " null " . . . . . Constant Constant : : i n t : : 1 0 . . . . P o s t f i x I n c D e c E x p r e s s i o n Operator ::++ . . . . . Variable Variable : : i " null " . . . . Statement } lviii Luís Laranjeira - PJMAS . . . . . CompoundStatement } . . . . . . Statement <j s p : s c r i p t l e t > . . . . . . . EmbeddedHtml <j s p : s c r i p t l e t > . . . . . . . . JspPage i t e r a c a o aqui . . . . . . . . . . . . HtmlBlock HtmlBlock : : i t e r a c a o aqui . . . . . . . . . Statement ; . . . . . . . ExpressionStatement ) . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . V a r i a b l e V a r i a b l e : : out " n u l l " . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . Variable Variable : : p r i n t l n " null " . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . Variable Variable : : id " null " . JspPage . . HtmlBlock HtmlBlock : : . JspPage body> . . HtmlBlock HtmlBlock : : < / body> (...) Resultado do Teste: Pass. lix Luís Laranjeira - PJMAS ID Teste: 19 Data: 23/04/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Deteção de JSP Declarations, no formato XML e JSP, e de código Java no seu interior. Descrição: Ficheiro teste.jsp, com código Java usando JSP Declarations. Conteúdo do ficheiro de input: (...) <body> <%! p u b l i c boolean c a l c ( i n t num ) { i f ( num<10) r e t u r n t r u e ; return false ; } %> <j s p : d e c l a r a t i o n > p u b l i c i n t count ( i n t [ ] c ) { i n t count =0; f o r ( i n t i =0; i < c . l e n g t h ; i ++){ count+=c [ i ] ; } r e t u r n count ; } </ j s p : d e c l a r a t i o n > </body> (...) Resultado Parsing Esperado: Parsing sem qualquer erro e árvore obtida preenchida corretamente. Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado: (...) . JspPage head> <body> . . HtmlBlock HtmlBlock : : < / head> <body> . JspPage %> . . J s p D e c l a r a t i o n %> . . . MemberDeclaration F u n c t i o n : : c a l c p u b l i c b o o l . . . . Type boolean . . . . . BasicType boolean . . . . P a r a m e t e r L i s t num . . . . . Parameter V a r i a b l e : : i n t e g e r : : num " n u l l " . . . . . . Type i n t . . . . . . . BasicType i n t . . . . . . V a r i a b l e V a r i a b l e : : i n t e g e r : : num " n u l l " . . . . CompoundStatement } . . . . . Statement ; . . . . . . SelectionStatement I f _ e l s e i f _ e l s e . . . . . . . RelationalExpression < . . . . . . . . V a r i a b l e V a r i a b l e : : num " n u l l " . . . . . . . . Constant Constant : : i n t : : 1 0 . . . . . . . Statement ; . . . . . . . . JumpStatement JumpStatement : : r e t u r n lx Luís Laranjeira - PJMAS . . . . . . . . . Constant Constant : : p r e d e f i n e d : : t r u e . . . . . Statement ; . . . . . . JumpStatement JumpStatement : : r e t u r n . . . . . . . Constant Constant : : p r e d e f i n e d : : f a l s e . JspPage . . HtmlBlock HtmlBlock : : . JspPage </ j s p : d e c l a r a t i o n > . . J s p D e c l a r a t i o n </ j s p : d e c l a r a t i o n > . . . MemberDeclaration F u n c t i o n : : count p u b l i c i n t e g e r . . . . Type i n t . . . . . BasicType i n t . . . . ParameterList c . . . . . Parameter V a r i a b l e : : a r r a y : : c " A r r a y V a r i a (...) > []" . . . . . . Type ] . . . . . . . ReferenceType [ ] . . . . . . . . BasicType i n t . . . . . . Variable Variable : : array : : c " ArrayVaria (...) > []" . . . . CompoundStatement } . . . . . Statement ; . . . . . . ExpressionStatement 0 . . . . . . . VariableDeclaration 0 . . . . . . . . Type i n t . . . . . . . . . BasicType i n t . . . . . . . . V a r i a b l e 2 V a r i a b l e : : i n t e g e r : : count " n u l l " . . . . . . . . . Constant Constant : : i n t : : 0 . . . . . Statement } . . . . . . IterationStatement IterationStatement : : for . . . . . . . VariableDeclaration 0 . . . . . . . . Type i n t . . . . . . . . . BasicType i n t . . . . . . . . Variable2 Variable : : integer : : i " null " . . . . . . . . . Constant Constant : : i n t : : 0 . . . . . . . RelationalExpression < . . . . . . . . Variable Variable : : i " null " . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . Variable Variable : : c " null " . . . . . . . . . Variable Variable : : length " null " . . . . . . . P o s t f i x I n c D e c E x p r e s s i o n Operator ::++ . . . . . . . . Variable Variable : : i " null " . . . . . . . Statement } . . . . . . . . CompoundStatement } . . . . . . . . . Statement ; . . . . . . . . . . ExpressionStatement ] . . . . . . . . . . . AssignmentExpression ] . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : count " n u l l " . . . . . . . . . . . . AssignmentOperator Operator ::+= . . . . . . . . . . . . PostfixExpression PostfixExpression : : [ . . . . . . . . . . . . . Variable Variable : : c " null " . . . . . . . . . . . . . Variable Variable : : i " null " . . . . . Statement ; . . . . . . JumpStatement JumpStatement : : r e t u r n . . . . . . . V a r i a b l e V a r i a b l e : : count " n u l l " . JspPage . . HtmlBlock HtmlBlock : : . JspPage body> . . HtmlBlock HtmlBlock : : < / body> (...) Resultado do Teste: Pass. lxi Luís Laranjeira - PJMAS ID Teste: 20 Data: 24/04/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Deteção de JSP Expressions, no formato XML e JSP, e de código Java no seu interior. Descrição: Ficheiro teste.jsp, com código Java usando JSP Expressions. Conteúdo do ficheiro de input: (...) <body> <%=r e q u e s t . getParameter ( " i d " )%> <j s p : e x p r e s s i o n > r e q u e s t . getParameter ( " i d " ) </ j s p : e x p r e s s i o n > </body> (...) Resultado Parsing Esperado: Parsing sem qualquer erro e árvore obtida preenchida corretamente. Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado: (...) . JspPage head> <body> . . HtmlBlock HtmlBlock : : < / head> <body> . JspPage %> . . HtmlBlock %> . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . Variable Variable : : request " n u l l " . . . . PostfixExpression PostfixExpression : : ( . . . . . V a r i a b l e V a r i a b l e : : getParameter " n u l l " . . . . . ArgumentExpressionList ) . . . . . . Constant Constant : : s t r i n g : : " i d " . JspPage . . HtmlBlock HtmlBlock : : . JspPage </ j s p : e x p r e s s i o n > . . HtmlBlock </ j s p : e x p r e s s i o n > . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . Variable Variable : : request " n u l l " . . . . PostfixExpression PostfixExpression : : ( . . . . . V a r i a b l e V a r i a b l e : : getParameter " n u l l " . . . . . ArgumentExpressionList ) . . . . . . Constant Constant : : s t r i n g : : " i d " . JspPage . . HtmlBlock HtmlBlock : : . JspPage body> . . HtmlBlock HtmlBlock : : < / body> (...) Resultado do Teste: Pass. lxii Luís Laranjeira - PJMAS ID Teste: 21 Data: 29/04/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Deteção de JSP Directive, no formato XML e JSP. Descrição: Ficheiro teste.jsp, com código Java usando JSP Directive, contendo vários imports, definições da própria “página”, redirecionamento em caso de erro e include de outros ficheiros. Conteúdo do ficheiro de input: <%@ page language=" j a v a " contentType=" t e x t / html ; c h a r s e t=UTF−8 " pageEncoding= ’UTF−8 ’%> <html> <head> <meta h t t p−e q u i v=" Content−Type " c o n t e n t=" t e x t / html ; c h a r s e t=UTF−8 "> < t i t l e >T i t u l o </ t i t l e > </head> <%@ page i m p o r t=" j a v a . u t i l . ∗ , j a v a . i o . ∗ " errorPage= ’ NewFile . j s p ’ %> <j s p : d i r e c t i v e . page i m p o r t=" j a v a . u t i l . ∗ , j a v a . i o . ∗ " errorPage= ’ NewFile . j s p ’> </ j s p : d i r e c t i v e . page> <body> <%@ i n c l u d e f i l e =" h e l l o . j s p " %> </body> </ html> Resultado Parsing Esperado: Parsing sem qualquer erro e árvore obtida preenchida corretamente. Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado: ASTRoot . JspPage %> . . J s p D i r e c t i v e %> . . . P a g e D i r e c t i v e L i s t language . . . . Constant Constant : : s t r i n g : : j a v a . . . P a g e D i r e c t i v e L i s t contentType . . . . Constant Constant : : s t r i n g : : t e x t / html ; c ( . . . ) UTF−8 . . . P a g e D i r e c t i v e L i s t pageEncoding . . . . Constant Constant : : s t r i n g : : UTF−8 . JspPage <html> <head> <meta h t t p−equ ( . . . ) itulo . . HtmlBlock HtmlBlock : : <html> <head> <me ( . . . ) i t u l o . JspPage t i t l e > . . HtmlBlock HtmlBlock : : < / t i t l e > . JspPage head> . . HtmlBlock HtmlBlock : : < / head> . JspPage %> . . J s p D i r e c t i v e %> . . . PageDirectiveList Include : : import . . . . JspPageIncludes " . . . . . J s p P a g e I n c l u d e Constant : : s t r i n g : : j a v a . u t i l . ∗ . . . . . J s p P a g e I n c l u d e Constant : : s t r i n g : : j a v a . i o . ∗ . . . P a g e D i r e c t i v e L i s t I n c l u d e : : errorPage . . . . JspPageIncludes ’ lxiii Luís Laranjeira - PJMAS . . . . . J s p P a g e I n c l u d e Constant : : s t r i n g : : NewFile . j s p . JspPage <body> . . HtmlBlock HtmlBlock : : <body> . JspPage %> . . J s p D i r e c t i v e %> . . . IncludeDirectiveList Include : : include . . . . Constant Constant : : s t r i n g : : h e l l o . j s p . JspPage . . HtmlBlock HtmlBlock : : . JspPage body> . . HtmlBlock HtmlBlock : : < / body> . JspPage html> . . HtmlBlock HtmlBlock : : < / html> Resultado do Teste: Pass. lxiv Luís Laranjeira - PJMAS ID Teste: 22 Data: 06/05/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Deteção de JSP Standad Actions. Descrição: Ficheiro teste.jsp, com expressões XML, criação de um Bean e modificação de atributos do mesmo. Declaração também de um Forward com alguns parâmetros. Conteúdo do ficheiro de input: <html> <head> <meta h t t p−e q u i v=" Content−Type " c o n t e n t=" t e x t / html ; c h a r s e t=UTF−8 "> < t i t l e >T i t u l o </ t i t l e > </head> <j s p : useBean i d=" myBean " c l a s s=" J s p U s e r . User " scope=" s e s s i o n "> <j s p : s e t P r o p e r t y name=" myBean " p r o p e r t y=" name " param=" i d " /> <j s p : s e t P r o p e r t y p r o p e r t y=" name " param=" i d " name=" myBean " /> <j s p : s e t P r o p e r t y name=" myBean " p r o p e r t y=" address " v a l u e=" 0 0 7 , G a l i No . 2 " /> </ j s p : useBean> <body> <j s p : g e t P r o p e r t y p r o p e r t y=" name " name=" myBean " /> </body> <j s p : f o r w a r d page=" header . j s p ? i d =20 "> <j s p : params> <j s p : param name=" v a r i a b l e 1 " v a l u e=" Home " /> <j s p : param name=" v a r i a b l e 2 " v a l u e=" Products " /> <j s p : param name=" v a r i a b l e 3 " v a l u e=" S e r v i c e s " /> <j s p : param name=" v a r i a b l e 4 " v a l u e=" Company P r o f i l e " /> </ j s p : params> </ j s p : forward > </ html> Resultado Parsing Esperado: Parsing sem qualquer erro e árvore obtida preenchida corretamente. Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado: ASTRoot . JspPage html> <head> <meta h t t p−e q u i v= ( . . . ) i t u l o . . HtmlBlock HtmlBlock : : < html> <head> <meta ( . . . ) itulo . . . JspCheck <html> <head> <meta h t t p−e q u i v ( . . . ) itulo . JspPage t i t l e > . . HtmlBlock HtmlBlock : : < / t i t l e > . JspPage head> . . HtmlBlock HtmlBlock : : < / head> . JspPage > . . JspTagStatement > . . . J s p S t a n d a r d A c t i o n useBean . . . . JspStandardActionUseBean " . . . . . JspStandardActionParameters id . . . . . . A t t r i b u t e V a l u e [ myBean ] . . . . . JspStandardActionParameters c l a s s . . . . . . A t t r i b u t e V a l u e [ J s p U s e r . User ] lxv Luís Laranjeira - PJMAS . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s scope . . . . . . AttributeValue [ session ] . . . . JspPage . . . . . HtmlBlock HtmlBlock : : . . . . JspPage /> . . . . . JspTagStatement /> . . . . . . JspStandardAction setProperty . . . . . . . JspStandardActionSetProperty " . . . . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s name . . . . . . . . . A t t r i b u t e V a l u e [ myBean ] . . . . . . . . JspStandardActionParameters property . . . . . . . . . A t t r i b u t e V a l u e [ name ] . . . . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s param . . . . . . . . . AttributeValue [ id ] . . . . JspPage . . . . . HtmlBlock HtmlBlock : : . . . . JspPage /> . . . . . JspTagStatement /> . . . . . . JspStandardAction setProperty . . . . . . . JspStandardActionSetProperty " . . . . . . . . JspStandardActionParameters property . . . . . . . . . A t t r i b u t e V a l u e [ name ] . . . . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s param . . . . . . . . . AttributeValue [ id ] . . . . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s name . . . . . . . . . A t t r i b u t e V a l u e [ myBean ] . . . . JspPage . . . . . HtmlBlock HtmlBlock : : . . . . JspPage /> . . . . . JspTagStatement /> . . . . . . JspStandardAction setProperty . . . . . . . JspStandardActionSetProperty " . . . . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s name . . . . . . . . . A t t r i b u t e V a l u e [ myBean ] . . . . . . . . JspStandardActionParameters property . . . . . . . . . A t t r i b u t e V a l u e [ address ] . . . . . . . . JspStandardActionParameters value . . . . . . . . . A t t r i b u t e V a l u e [ 0 0 7 , G a l i No . 2 ] . . . . JspPage . . . . . HtmlBlock HtmlBlock : : . JspPage <body> . . HtmlBlock HtmlBlock : : <body> . JspPage /> . . JspTagStatement /> . . . J s p S t a n d a r d A c t i o n echo . . . . JspStandardActionGetProperty " . . . . . JspStandardActionParameters property . . . . . . A t t r i b u t e V a l u e [ name ] . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s name . . . . . . A t t r i b u t e V a l u e [ myBean ] . JspPage . . HtmlBlock HtmlBlock : : . JspPage body> . . HtmlBlock HtmlBlock : : < / body> . JspPage > . . JspTagStatement > . . . JspStandardAction Include : : forward . . . . JspStandardActionInclude " . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s page . . . . . . A t t r i b u t e V a l u e [ header . j s p ? i d =20] . . . . RequestArguments . . . . . JspPage lxvi Luís Laranjeira - PJMAS . . . . . . HtmlBlock HtmlBlock : : . . . . . JspPage > . . . . . . JspTagStatement > . . . . . . . J s p S t a n d a r d A c t i o n params . . . . . . . . RequestArguments . . . . . . . . . JspPage . . . . . . . . . . HtmlBlock HtmlBlock : : . . . . . . . . . JspPage /> . . . . . . . . . . JspTagStatement /> . . . . . . . . . . . J s p S t a n d a r d A c t i o n param . . . . . . . . . . . . JspStandardActionParameter " . . . . . . . . . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s name . . . . . . . . . . . . . . AttributeValue [ variable1 ] . . . . . . . . . . . . . JspStandardActionParameters value . . . . . . . . . . . . . . A t t r i b u t e V a l u e [ Home ] . . . . . . . . . JspPage . . . . . . . . . . HtmlBlock HtmlBlock : : . . . . . . . . . JspPage /> . . . . . . . . . . JspTagStatement /> . . . . . . . . . . . J s p S t a n d a r d A c t i o n param . . . . . . . . . . . . JspStandardActionParameter " . . . . . . . . . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s name . . . . . . . . . . . . . . AttributeValue [ variable2 ] . . . . . . . . . . . . . JspStandardActionParameters value . . . . . . . . . . . . . . A t t r i b u t e V a l u e [ Products ] . . . . . . . . . JspPage . . . . . . . . . . HtmlBlock HtmlBlock : : . . . . . . . . . JspPage /> . . . . . . . . . . JspTagStatement /> . . . . . . . . . . . J s p S t a n d a r d A c t i o n param . . . . . . . . . . . . JspStandardActionParameter " . . . . . . . . . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s name . . . . . . . . . . . . . . AttributeValue [ variable3 ] . . . . . . . . . . . . . JspStandardActionParameters value . . . . . . . . . . . . . . AttributeValue [ Services ] . . . . . . . . . JspPage . . . . . . . . . . HtmlBlock HtmlBlock : : . . . . . . . . . JspPage /> . . . . . . . . . . JspTagStatement /> . . . . . . . . . . . J s p S t a n d a r d A c t i o n param . . . . . . . . . . . . JspStandardActionParameter " . . . . . . . . . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s name . . . . . . . . . . . . . . AttributeValue [ variable4 ] . . . . . . . . . . . . . JspStandardActionParameters value . . . . . . . . . . . . . . A t t r i b u t e V a l u e [ Company P r o f i l e ] . . . . . . . . . JspPage . . . . . . . . . . HtmlBlock HtmlBlock : : . . . . . JspPage . . . . . . HtmlBlock HtmlBlock : : . JspPage . . HtmlBlock HtmlBlock : : . JspPage html> . . HtmlBlock HtmlBlock : : < / html> Resultado do Teste: Pass. lxvii Luís Laranjeira - PJMAS G.1.3 Testes à alteração de Ciclos ID Teste: 23 Data: 13/05/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Alteração à AST nos ciclos for. Descrição: Ficheiro teste.java, contendo um ciclo for. Conteúdo do ficheiro de input: (...) for ( String str : arr ) { System . out . p r i n t l n ( s t r ) ; } (...) Resultado Parsing Esperado: Todos os nós alterados corretamente e. Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado sem Modificação: (...) . . . . . Statement } . . . . . . IterationStatement IterationStatement : : foreach . . . . . . . VariableDeclaration str . . . . . . . . Type S t r i n g . . . . . . . . . ReferenceType S t r i n g . . . . . . . . . . ClassOrInterfaceType Class : : String ( , ) . . . . . . . . Variable2 Variable : : s tr i ng : : s t r " null " . . . . . . . Variable Variable : : arr " null " . . . . . . . Statement } . . . . . . . . CompoundStatement } . . . . . . . . . Statement ; . . . . . . . . . . ExpressionStatement ) . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : System " n u l l " . . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : out " n u l l " . . . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . . . Variable Variable : : p r i n t l n " null " . . . . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . . . . . Variable Variable : : st r " null " (...) Output observado com Modificação: (...) . . . . . Statement . . . . . . ExpressionStatement . . . . . . . VariableDeclaration . . . . . . . . Type i n t . . . . . . . . . BasicType i n t lxviii Luís Laranjeira - PJMAS . . . . . . . . Variable2 Variable : : integer : : i t e r a t o r 0 " null " . . . . . . . . . Constant Constant : : i n t : : 0 . . . . . Statement } . . . . . . IterationStatement IterationStatement : : while . . . . . . . RelationalExpression < . . . . . . . . Variable Variable : : integer : : i te r a t o r 0 " null " . . . . . . . . PostfixExpression . . . . . . . . . Variable Variable : : arr " null " . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . Variable Variable : : size " null " . . . . . . . . . . ArgumentExpressionList . . . . . . . Statement } . . . . . . . . CompoundStatement } . . . . . . . . . Statement . . . . . . . . . . ExpressionStatement . . . . . . . . . . . VariableDeclaration str . . . . . . . . . . . . Type S t r i n g . . . . . . . . . . . . . ReferenceType S t r i n g . . . . . . . . . . . . . . ClassOrInterfaceType Class : : String ( , ) . . . . . . . . . . . . Variable2 Variable : : st r in g : : s t r " null " . . . . . . . . . . . . . PostfixExpression . . . . . . . . . . . . . . Variable Variable : : arr " null " . . . . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : get " n u l l " . . . . . . . . . . . . . . . ArgumentExpressionList . . . . . . . . . . . . . . . . Variable Variable : : integer : : i t e r a t o r 0 " null " . . . . . . . . . Statement ; . . . . . . . . . . ExpressionStatement ) . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : System " n u l l " . . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : out " n u l l " . . . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . . . Variable Variable : : p r i n t l n " null " . . . . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . . . . . Variable Variable : : str " null " . . . . . . . . . Statement . . . . . . . . . . ExpressionStatement . . . . . . . . . . . P o s t f i x I n c D e c E x p r e s s i o n Operator ::++ . . . . . . . . . . . . Variable Variable : : integer : : i t e r a t o r 0 " null " (...) Resultado do Teste: Pass. lxix Luís Laranjeira - PJMAS ID Teste: 24 Data: 13/05/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Alteração à AST nos ciclos for. Descrição: Ficheiro teste.java, contendo um ciclo for. Conteúdo do ficheiro de input: (...) f o r ( i n t i =0; i <a r r . s i z e ( ) ; i ++){ System . out . p r i n t l n ( a r r . get ( i ) ) ; } (...) Resultado Parsing Esperado: Todos os nós alterados corretamente e. Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado sem Modificação: (...) . . . . . Statement } . . . . . . IterationStatement IterationStatement : : for . . . . . . . ForInit 0 . . . . . . . . VariableDeclaration 0 . . . . . . . . . Type i n t . . . . . . . . . . BasicType i n t . . . . . . . . . Variable2 Variable : : integer : : i " null " . . . . . . . . . . Constant Constant : : i n t : : 0 . . . . . . . RelationalExpression < . . . . . . . . Variable Variable : : i " null " . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . Variable Variable : : arr " null " . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . Variable Variable : : size " null " . . . . . . . . . . ArgumentExpressionList ) . . . . . . . ForUpdate ++ . . . . . . . . P o s t f i x I n c D e c E x p r e s s i o n Operator ::++ . . . . . . . . . Variable Variable : : i " null " . . . . . . . Statement } . . . . . . . . CompoundStatement } . . . . . . . . . Statement ; . . . . . . . . . . ExpressionStatement ) . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : System " n u l l " . . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : out " n u l l " . . . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . . . Variable Variable : : p r i n t l n " null " . . . . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . . . . . Variable Variable : : arr " null " . . . . . . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : get " n u l l " . . . . . . . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . . . . . . . . Variable Variable : : i " null " (...) lxx Luís Laranjeira - PJMAS Output observado com Modificação: (...) . . . . . Statement . . . . . . ExpressionStatement . . . . . . . VariableDeclaration 0 . . . . . . . . Type i n t . . . . . . . . . BasicType i n t . . . . . . . . Variable2 Variable : : integer : : i " null " . . . . . . . . . Constant Constant : : i n t : : 0 . . . . . Statement } . . . . . . IterationStatement IterationStatement : : while . . . . . . . RelationalExpression < . . . . . . . . Variable Variable : : i " null " . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . Variable Variable : : arr " null " . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . Variable Variable : : size " null " . . . . . . . . . . ArgumentExpressionList ) . . . . . . . Statement } . . . . . . . . CompoundStatement } . . . . . . . . . Statement ; . . . . . . . . . . ExpressionStatement ) . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : System " n u l l " . . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : out " n u l l " . . . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . . . Variable Variable : : p r i n t l n " null " . . . . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . . . . . Variable Variable : : arr " null " . . . . . . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . . . . . . V a r i a b l e V a r i a b l e : : get " n u l l " . . . . . . . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . . . . . . . . Variable Variable : : i " null " . . . . . . . . . Statement . . . . . . . . . . ExpressionStatement . . . . . . . . . . . P o s t f i x I n c D e c E x p r e s s i o n Operator ::++ . . . . . . . . . . . . Variable Variable : : i " null " (...) Resultado do Teste: Pass. lxxi Luís Laranjeira - PJMAS G.1.4 Testes à Expansão de Múltiplas Exceções nos Try-Catch ID Teste: 25 Data: 08/04/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Expansão de múltiplas exceções nos Try-Catch. Descrição: Ficheiro Teste.java, com um Try-Catch utilizando novas funcionalidades do JDK 1.7 . Conteúdo do ficheiro de input: (...) t r y ( InputStream i n = new F i l e I n p u t S t r e a m ( s r c ) ; OutputStream out = new FileOutputStream ( d e s t ) ) { } (...) byte [ ] b u f = new byte [ 8 1 9 2 ] ; i n t n=8192; out . w r i t e ( buf , 0 , n ) ; } c a t c h ( FileNotFoundException | I O E x c e p t i o n e ) { e . printStackTrace ( ) ; Resultado Parsing Esperado: Parsing sem qualquer erro e árvore obtida preenchida corretamente. Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado sem Expansão: (...) . . . . . Statement } . . . . . . TryStatement } . . . . . . . TryUsing ) . . . . . . . . VariableDeclaration ) . . . . . . . . . Type InputStream . . . . . . . . . . ReferenceType InputStream . . . . . . . . . . . C l a s s O r I n t e r f a c e T y p e C l a s s : : InputStream ( , ) . . . . . . . . . V a r i a b l e 2 V a r i a b l e : : o b j e c t : : i n " C l a s s : : InputStream ( , ) " . . . . . . . . . . ClassInstantiation ) . . . . . . . . . . . Type F i l e I n p u t S t r e a m . . . . . . . . . . . . ReferenceType F i l e I n p u t S t r e a m . . . . . . . . . . . . . ClassOrInterfaceType Class : : FileInputStream ( , ) . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . . Variable Variable : : src " null " . . . . . . . . VariableDeclaration ) . . . . . . . . . Type OutputStream . . . . . . . . . . ReferenceType OutputStream . . . . . . . . . . . C l a s s O r I n t e r f a c e T y p e C l a s s : : OutputStream ( , ) . . . . . . . . . V a r i a b l e 2 V a r i a b l e : : o b j e c t : : out " C l a s s : : OutputStream ( , ) " . . . . . . . . . . ClassInstantiation ) . . . . . . . . . . . Type FileOutputStream . . . . . . . . . . . . ReferenceType FileOutputStream . . . . . . . . . . . . . C l a s s O r I n t e r f a c e T y p e C l a s s : : FileOutputStream ( , ) . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . . Variable Variable : : dest " n u l l " . . . . . . . CompoundStatement } . . . . . . . . Statement ; . . . . . . . . . ExpressionStatement ] lxxii Luís Laranjeira - PJMAS . . . . . . . . . . VariableDeclaration ] . . . . . . . . . . . Type ] . . . . . . . . . . . . ReferenceType [ ] . . . . . . . . . . . . . BasicType byte . . . . . . . . . . . V a r i a b l e 2 V a r i a b l e : : a r r a y : : b u f " A r r a y V a r i a b l e <C l a s s : : byte ( , )> [ ] " . . . . . . . . . . . . ClassInstantiation ] . . . . . . . . . . . . . Type byte . . . . . . . . . . . . . . BasicType byte . . . . . . . . . . . . . Constant Constant : : i n t : : 8 1 9 2 . . . . . . . . Statement ; . . . . . . . . . E x p r e s s i o n S t a t e m e n t 8192 . . . . . . . . . . V a r i a b l e D e c l a r a t i o n 8192 . . . . . . . . . . . Type i n t . . . . . . . . . . . . BasicType i n t . . . . . . . . . . . Variable2 Variable : : integer : : n " null " . . . . . . . . . . . . Constant Constant : : i n t : : 8 1 9 2 . . . . . . . . Statement ; . . . . . . . . . ExpressionStatement ) . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . V a r i a b l e V a r i a b l e : : out " n u l l " . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . Variable Variable : : write " null " . . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . . . Variable Variable : : buf " n u l l " . . . . . . . . . . . . . Constant Constant : : i n t : : 0 . . . . . . . . . . . . . Variable Variable : : n " null " . . . . . . . CatchClause [ CatchClause ] . . . . . . . . V a r i a b l e V a r i a b l e : : o b j e c t : : e " C l a s s : : FileNotFoundException ( , ) " . . . . . . . . CompoundStatement } . . . . . . . . . Statement ; . . . . . . . . . . ExpressionStatement ) . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . Variable Variable : : e " null " . . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . . Variable Variable : : printStackTrace " null " . . . . . . . . . . . . . ArgumentExpressionList ) (...) Output observado com Expansão: (...) . . . . . . TryStatement } . . . . . . . TryUsing ) . . . . . . . . VariableDeclaration ) . . . . . . . . . Type InputStream . . . . . . . . . . ReferenceType InputStream . . . . . . . . . . . C l a s s O r I n t e r f a c e T y p e C l a s s : : InputStream ( , ) . . . . . . . . . V a r i a b l e 2 V a r i a b l e : : o b j e c t : : i n " C l a s s : : InputStream ( , ) " . . . . . . . . . . ClassInstantiation ) . . . . . . . . . . . Type F i l e I n p u t S t r e a m . . . . . . . . . . . . ReferenceType F i l e I n p u t S t r e a m . . . . . . . . . . . . . ClassOrInterfaceType Class : : FileInputStream ( , ) . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . . Variable Variable : : src " null " . . . . . . . . VariableDeclaration ) . . . . . . . . . Type OutputStream . . . . . . . . . . ReferenceType OutputStream . . . . . . . . . . . C l a s s O r I n t e r f a c e T y p e C l a s s : : OutputStream ( , ) . . . . . . . . . V a r i a b l e 2 V a r i a b l e : : o b j e c t : : out " C l a s s : : OutputStream ( , ) " . . . . . . . . . . ClassInstantiation ) lxxiii Luís Laranjeira - PJMAS . . . . . . . . . . . Type FileOutputStream . . . . . . . . . . . . ReferenceType FileOutputStream . . . . . . . . . . . . . C l a s s O r I n t e r f a c e T y p e C l a s s : : FileOutputStream ( , ) . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . . Variable Variable : : dest " n u l l " . . . . . . . CompoundStatement } . . . . . . . . Statement ; . . . . . . . . . ExpressionStatement ] . . . . . . . . . . VariableDeclaration ] . . . . . . . . . . . Type ] . . . . . . . . . . . . ReferenceType [ ] . . . . . . . . . . . . . BasicType byte . . . . . . . . . . . V a r i a b l e 2 V a r i a b l e : : a r r a y : : b u f " A r r a y V a r i a b l e <C l a s s : : byte ( , )> [ ] " . . . . . . . . . . . . ClassInstantiation ] . . . . . . . . . . . . . Type byte . . . . . . . . . . . . . . BasicType byte . . . . . . . . . . . . . Constant Constant : : i n t : : 8 1 9 2 . . . . . . . . Statement ; . . . . . . . . . E x p r e s s i o n S t a t e m e n t 8192 . . . . . . . . . . V a r i a b l e D e c l a r a t i o n 8192 . . . . . . . . . . . Type i n t . . . . . . . . . . . . BasicType i n t . . . . . . . . . . . Variable2 Variable : : integer : : n " null " . . . . . . . . . . . . Constant Constant : : i n t : : 8 1 9 2 . . . . . . . . Statement ; . . . . . . . . . ExpressionStatement ) . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . V a r i a b l e V a r i a b l e : : out " n u l l " . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . Variable Variable : : write " null " . . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . . . . . . . Variable Variable : : buf " n u l l " . . . . . . . . . . . . . Constant Constant : : i n t : : 0 . . . . . . . . . . . . . Variable Variable : : n " null " . . . . . . . CatchClause [ CatchClause ] . . . . . . . . V a r i a b l e V a r i a b l e : : o b j e c t : : e " C l a s s : : FileNotFoundException ( , ) " . . . . . . . . CompoundStatement } . . . . . . . . . Statement ; . . . . . . . . . . ExpressionStatement ) . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . Variable Variable : : e " null " . . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . . Variable Variable : : printStackTrace " null " . . . . . . . . . . . . . ArgumentExpressionList ) . . . . . . . CatchClause . . . . . . . . Variable Variable : : o b j e c t : : e " Class : : IOException ( , ) " . . . . . . . . CompoundStatement } . . . . . . . . . Statement ; . . . . . . . . . . ExpressionStatement ) . . . . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . . . . Variable Variable : : e " null " . . . . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . . . . Variable Variable : : printStackTrace " null " . . . . . . . . . . . . . ArgumentExpressionList ) (...) Resultado do Teste: Pass. lxxiv Luís Laranjeira - PJMAS G.1.5 Testes às Alterações aos nós da AST nas JSP ID Teste: 26 Data: 08/05/2013 Tipo de Teste: Teste à funcionalidade. Funcionalidade: Alterações aos nós da AST nas JSP. Descrição: Ficheiro teste.jsp, com expressões XML, criação de um Bean e modificação de atributos do mesmo. Declaração também de um Include e um Forward com alguns parâmetros. Conteúdo do ficheiro de input: <html> <head> <meta h t t p−e q u i v=" Content−Type " c o n t e n t=" t e x t / html ; c h a r s e t=UTF−8 "> < t i t l e >T i t u l o </ t i t l e > </head> <j s p : useBean i d=" myBean " c l a s s=" J s p U s e r . User " scope=" s e s s i o n "> <j s p : s e t P r o p e r t y name=" myBean " p r o p e r t y=" name " param=" i d " /> <j s p : s e t P r o p e r t y p r o p e r t y=" name " param=" i d " name=" myBean " /> <j s p : s e t P r o p e r t y name=" myBean " p r o p e r t y=" address " v a l u e=" 0 0 7 , G a l i No . 2 " /> </ j s p : useBean> <body> <j s p : g e t P r o p e r t y p r o p e r t y=" name " name=" myBean " /> </body> <j s p : i n c l u d e page=" c l i e n t . j s p ? i d =10 " /> <j s p : f o r w a r d page=" header . j s p ? i d =20 "> <j s p : params> <j s p : param name=" v a r i a b l e 1 " v a l u e=" Home " /> <j s p : param name=" v a r i a b l e 2 " v a l u e=" Products " /> </ j s p : params> </ j s p : forward > </ html> Resultado Parsing Esperado: Parsing sem qualquer erro e árvore obtida preenchida corretamente. Resultado Parsing Obtido: Parsing sem qualquer erro detetado e árvore obtida preenchida corretamente. Output observado antes das alterações: ASTRoot . JspPage html> <head> <meta h t t p−e q u i v= ( . . . ) i t u l o . . HtmlBlock HtmlBlock : : < html> <head> <meta ( . . . ) itulo . . . JspCheck <html> <head> <meta h t t p−e q u i v ( . . . ) itulo . JspPage t i t l e > . . HtmlBlock HtmlBlock : : < / t i t l e > . JspPage head> . . HtmlBlock HtmlBlock : : < / head> . JspPage > . . JspTagStatement > . . . J s p S t a n d a r d A c t i o n useBean . . . . JspStandardActionUseBean " . . . . . JspStandardActionParameters id . . . . . . A t t r i b u t e V a l u e [ myBean ] lxxv Luís Laranjeira - PJMAS . . . . . JspStandardActionParameters c l a s s . . . . . . A t t r i b u t e V a l u e [ J s p U s e r . User ] . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s scope . . . . . . AttributeValue [ session ] . . . . JspPage . . . . . HtmlBlock HtmlBlock : : . . . . JspPage /> . . . . . JspTagStatement /> . . . . . . JspStandardAction setProperty . . . . . . . JspStandardActionSetProperty " . . . . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s name . . . . . . . . . A t t r i b u t e V a l u e [ myBean ] . . . . . . . . JspStandardActionParameters property . . . . . . . . . A t t r i b u t e V a l u e [ name ] . . . . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s param . . . . . . . . . AttributeValue [ id ] . . . . JspPage . . . . . HtmlBlock HtmlBlock : : . . . . JspPage /> . . . . . JspTagStatement /> . . . . . . JspStandardAction setProperty . . . . . . . JspStandardActionSetProperty " . . . . . . . . JspStandardActionParameters property . . . . . . . . . A t t r i b u t e V a l u e [ name ] . . . . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s param . . . . . . . . . AttributeValue [ id ] . . . . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s name . . . . . . . . . A t t r i b u t e V a l u e [ myBean ] . . . . JspPage . . . . . HtmlBlock HtmlBlock : : . . . . JspPage /> . . . . . JspTagStatement /> . . . . . . JspStandardAction setProperty . . . . . . . JspStandardActionSetProperty " . . . . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s name . . . . . . . . . A t t r i b u t e V a l u e [ myBean ] . . . . . . . . JspStandardActionParameters property . . . . . . . . . A t t r i b u t e V a l u e [ address ] . . . . . . . . JspStandardActionParameters value . . . . . . . . . A t t r i b u t e V a l u e [ 0 0 7 , G a l i No . 2 ] . . . . JspPage . . . . . HtmlBlock HtmlBlock : : . JspPage <body> . . HtmlBlock HtmlBlock : : <body> . JspPage /> . . JspTagStatement /> . . . J s p S t a n d a r d A c t i o n echo . . . . JspStandardActionGetProperty " . . . . . JspStandardActionParameters property . . . . . . A t t r i b u t e V a l u e [ name ] . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s name . . . . . . A t t r i b u t e V a l u e [ myBean ] . JspPage . . HtmlBlock HtmlBlock : : . JspPage body> . . HtmlBlock HtmlBlock : : < / body> . JspPage /> . . JspTagStatement /> . . . JspStandardAction Include : : include . . . . JspStandardActionInclude " . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s page . . . . . . A t t r i b u t e V a l u e [ c l i e n t . j s p ? i d =10] lxxvi Luís Laranjeira - PJMAS . JspPage . . HtmlBlock HtmlBlock : : . JspPage > . . JspTagStatement > . . . JspStandardAction Include : : forward . . . . JspStandardActionInclude " . . . . . J s p S t a n d a r d A c t i o n P a r a m e t e r s page . . . . . . A t t r i b u t e V a l u e [ header . j s p ? i d =20] . . . . RequestArguments . . . . . JspPage . . . . . . HtmlBlock HtmlBlock : : . . . . . JspPage > . . . . . . JspTagStatement > . . . . . . . J s p S t a n d a r d A c t i o n params . . . . . . . . RequestArguments . . . . . . . . . JspPage . . . . . . . . . . HtmlBlock HtmlBlock : : . . . . . . . . . JspPage /> . . . . . . . . . . JspTagStatement /> . . . . . . . . . . . J s p S t a n d a r d A c t i o n param . . . . . . . . . . . . JspStandardActionParameter " . . . . . . . . . . . . . JspStandardActionParameters . . . . . . . . . . . . . . AttributeValue [ variable1 ] . . . . . . . . . . . . . JspStandardActionParameters . . . . . . . . . . . . . . A t t r i b u t e V a l u e [ Home ] . . . . . . . . . JspPage . . . . . . . . . . HtmlBlock HtmlBlock : : . . . . . . . . . JspPage /> . . . . . . . . . . JspTagStatement /> . . . . . . . . . . . J s p S t a n d a r d A c t i o n param . . . . . . . . . . . . JspStandardActionParameter " . . . . . . . . . . . . . JspStandardActionParameters . . . . . . . . . . . . . . AttributeValue [ variable2 ] . . . . . . . . . . . . . JspStandardActionParameters . . . . . . . . . . . . . . A t t r i b u t e V a l u e [ Products ] . . . . . . . . . JspPage . . . . . . . . . . HtmlBlock HtmlBlock : : . . . . . JspPage . . . . . . HtmlBlock HtmlBlock : : . JspPage . . HtmlBlock HtmlBlock : : . JspPage html> . . HtmlBlock HtmlBlock : : < / html> name value name value Output observado após as alterações: ASTRoot . JspPage html> <head> <meta h t t p−e q u i v= ( . . . ) i t u l o . . HtmlBlock HtmlBlock : : < html> <head> <meta ( . . . ) itulo . . . JspCheck <html> <head> <meta h t t p−e q u i v ( . . . ) itulo . JspPage t i t l e > . . HtmlBlock HtmlBlock : : < / t i t l e > . JspPage head> . . HtmlBlock HtmlBlock : : < / head> . JspPage > . . JspTagStatement > . . . J s p S t a n d a r d A c t i o n useBean . . . . V a r i a b l e V a r i a b l e : : o b j e c t : : myBean " C l a s s : : J s p U s e r . User ( , ) " . . . . JspPage . . . . . HtmlBlock HtmlBlock : : lxxvii Luís Laranjeira - PJMAS . . . . JspPage /> . . . . . JspTagStatement /> . . . . . . JspStandardAction setProperty . . . . . . . AssignmentExpression . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . V a r i a b l e V a r i a b l e : : myBean " n u l l " . . . . . . . . . V a r i a b l e V a r i a b l e : : name " n u l l " . . . . . . . . AssignmentOperator Operator : : = . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . Variable Variable : : request " n u l l " . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . V a r i a b l e V a r i a b l e : : getParameter " n u l l " . . . . . . . . . . ArgumentExpressionList . . . . . . . . . . . Constant Constant : : s t r i n g : : i d . . . . JspPage . . . . . HtmlBlock HtmlBlock : : . . . . JspPage /> . . . . . JspTagStatement /> . . . . . . JspStandardAction setProperty . . . . . . . AssignmentExpression . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . V a r i a b l e V a r i a b l e : : myBean " n u l l " . . . . . . . . . V a r i a b l e V a r i a b l e : : name " n u l l " . . . . . . . . AssignmentOperator Operator : : = . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . Variable Variable : : request " n u l l " . . . . . . . . . PostfixExpression PostfixExpression : : ( . . . . . . . . . . V a r i a b l e V a r i a b l e : : getParameter " n u l l " . . . . . . . . . . ArgumentExpressionList . . . . . . . . . . . Constant Constant : : s t r i n g : : i d . . . . JspPage . . . . . HtmlBlock HtmlBlock : : . . . . JspPage /> . . . . . JspTagStatement /> . . . . . . JspStandardAction setProperty . . . . . . . AssignmentExpression . . . . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . . . . V a r i a b l e V a r i a b l e : : myBean " n u l l " . . . . . . . . . V a r i a b l e V a r i a b l e : : address " n u l l " . . . . . . . . AssignmentOperator Operator : : = . . . . . . . . Constant Constant : : s t r i n g : : 0 0 7 , G a l i No . 2 . . . . JspPage . . . . . HtmlBlock HtmlBlock : : . JspPage <body> . . HtmlBlock HtmlBlock : : <body> . JspPage /> . . JspTagStatement /> . . . J s p S t a n d a r d A c t i o n echo . . . . ArgumentExpressionList . . . . . P o s t f i x E x p r e s s i o n P o s t f i x E x p r e s s i o n ::−> . . . . . . V a r i a b l e V a r i a b l e : : myBean " n u l l " . . . . . . V a r i a b l e V a r i a b l e : : name " n u l l " . JspPage . . HtmlBlock HtmlBlock : : . JspPage body> . . HtmlBlock HtmlBlock : : < / body> . JspPage /> . . JspTagStatement /> . . . JspStandardAction Include : : include . . . . Constant Constant : : s t r i n g : : c l i e n t . j s p ? i d =10 . JspPage . . HtmlBlock HtmlBlock : : lxxviii Luís Laranjeira - PJMAS . JspPage > . . JspTagStatement > . . . JspStandardAction Include : : forward . . . . Constant Constant : : s t r i n g : : header . j s p ? i d =20 . . . . RequestArguments . . . . . JspPage . . . . . . HtmlBlock HtmlBlock : : . . . . . JspPage > . . . . . . JspTagStatement > . . . . . . . J s p S t a n d a r d A c t i o n params . . . . . . . . RequestArguments . . . . . . . . . JspPage . . . . . . . . . . HtmlBlock HtmlBlock : : . . . . . . . . . JspPage /> . . . . . . . . . . JspTagStatement /> . . . . . . . . . . . J s p S t a n d a r d A c t i o n param . . . . . . . . . . . . AssignmentExpression . . . . . . . . . . . . . Variable Variable : : variable1 " null " . . . . . . . . . . . . . AssignmentOperator Operator : : = . . . . . . . . . . . . . Constant Constant : : s t r i n g : : Home . . . . . . . . . JspPage . . . . . . . . . . HtmlBlock HtmlBlock : : . . . . . . . . . JspPage /> . . . . . . . . . . JspTagStatement /> . . . . . . . . . . . J s p S t a n d a r d A c t i o n param . . . . . . . . . . . . AssignmentExpression . . . . . . . . . . . . . Variable Variable : : variable2 " null " . . . . . . . . . . . . . AssignmentOperator Operator : : = . . . . . . . . . . . . . Constant Constant : : s t r i n g : : Products . . . . . . . . . JspPage . . . . . . . . . . HtmlBlock HtmlBlock : : . . . . . JspPage . . . . . . HtmlBlock HtmlBlock : : . JspPage . . HtmlBlock HtmlBlock : : . JspPage html> . . HtmlBlock HtmlBlock : : < / html> Resultado do Teste: Pass. lxxix Luís Laranjeira - PJMAS G.2 Testes às Funcionalidades, Parsing de Projetos ID Teste: 1 Data: 27/05/2013 Tipo de Teste: Teste às funcionalidade com Parsing de Projeto. Descrição: Parsing ao projeto Eclipse JDK Core Component[5]. Resultado Parsing Esperado: Parsing a todos os ficheiros sem qualquer erro de parsing detetado. Resultado Parsing Obtido: Parsing de todos os ficheiros sem qualquer erro detetado. Output observado: t o t a l f i c h e i r o s : 2180 F i c h e i r o s J a v a : 2180 F i c h e i r o s JSP : 0 pasing completo : 2180 Erro de p a r s i n g : 0 t o t a l de l i n h a s : 1323642 Tempo t o t a l ( ms ) : 8475 mé d i a ( ms / l i n h a ) : 0.006402788669443852 Resultado do Teste: Pass. Nota: Foram ignorados alguns ficheiros de teste do projeto, criados para o compilador do eclipse, isto pois foi verificado que esses ficheiros não estavam completos, e são utilizados para testes ao completar automaticamente que o eclipse efetua, o que para o presente projeto não interessa. ID Teste: 2 Data: 27/05/2013 Tipo de Teste: Teste às funcionalidade com Parsing de Projeto. Descrição: Parsing ao projeto PMD[11]. Resultado Parsing Esperado: Parsing a todos os ficheiros sem qualquer erro de parsing detetado. Resultado Parsing Obtido: Parsing de todos os ficheiros sem qualquer erro detetado. Output observado: t o t a l f i c h e i r o s : 955 F i c h e i r o s J a v a : 955 F i c h e i r o s JSP : 0 pasing completo : 955 Erro de p a r s i n g : 0 t o t a l de l i n h a s : 101558 Tempo t o t a l ( ms ) : 3226 mé d i a ( ms / l i n h a ) : 0.031765099745957974 Resultado do Teste: Pass. Nota: Esta análise inclui os ficheiros de teste existentes utilizados pelo parser PMD. lxxx Luís Laranjeira - PJMAS ID Teste: 3 Data: 27/05/2013 Tipo de Teste: Teste às funcionalidade com Parsing de Projeto. Descrição: Parsing ao projeto Nymble[36]. Resultado Parsing Esperado: Parsing a todos os ficheiros sem qualquer erro de parsing detetado. Resultado Parsing Obtido: Parsing de todos os ficheiros sem qualquer erro detetado. Output observado: t o t a l f i c h e i r o s : 73 F i c h e i r o s J a v a : 16 F i c h e i r o s JSP : 57 pasing completo : 73 Erro de p a r s i n g : 0 t o t a l de l i n h a s : 8096 Tempo t o t a l ( ms ) : 334 mé d i a ( ms / l i n h a ) : 0.04125494071146245 Resultado do Teste: Pass. ID Teste: 4 Data: 28/05/2013 Tipo de Teste: Teste às funcionalidade com Parsing de Projeto. Descrição: Parsing aos projetos presentes nos samples do JavaEE/J2EE[37] Resultado Parsing Esperado: Parsing a todos os ficheiros sem qualquer erro de parsing detetado. Resultado Parsing Obtido: Parsing de todos os ficheiros sem qualquer erro detetado. Output observado: t o t a l f i c h e i r o s : 1803 F i c h e i r o s J a v a : 1464 F i c h e i r o s JSP : 339 pasing completo : 1803 Erro de p a r s i n g : 0 t o t a l de l i n h a s : 173915 Tempo t o t a l ( ms ) : 4438 mé d i a ( ms / l i n h a ) : 0.025518212920104647 Resultado do Teste: Pass. lxxxi Luís Laranjeira - PJMAS ID Teste: 5 Data: 28/05/2013 Tipo de Teste: Teste às funcionalidade com Parsing de Projeto. Descrição: Parsing ao projeto Airl[38] Resultado Parsing Esperado: Parsing a todos os ficheiros sem qualquer erro de parsing detetado. Resultado Parsing Obtido: Parsing de todos os ficheiros sem qualquer erro detetado. Output observado: t o t a l f i c h e i r o s : 62 F i c h e i r o s J a v a : 12 F i c h e i r o s JSP : 50 pasing completo : 62 Erro de p a r s i n g : 0 t o t a l de l i n h a s : 2890 Tempo t o t a l ( ms ) : 359 mé d i a ( ms / l i n h a ) : 0.12422145328719723 Resultado do Teste: Pass. ID Teste: 6 Data: 28/05/2013 Tipo de Teste: Teste às funcionalidade com Parsing de Projeto. Descrição: Parsing ao projeto Website visitor analyzer[39] Resultado Parsing Esperado: Parsing a todos os ficheiros sem qualquer erro de parsing detetado. Resultado Parsing Obtido: Parsing de todos os ficheiros sem qualquer erro detetado. Output observado: t o t a l f i c h e i r o s : 22 Ficheiros Java : 0 F i c h e i r o s JSP : 22 pasing completo : 22 Erro de p a r s i n g : 0 t o t a l de l i n h a s : 1703 Tempo t o t a l ( ms ) : 192 mé d i a ( ms / l i n h a ) : 0.11274221961244862 Resultado do Teste: Pass. lxxxii Luís Laranjeira - PJMAS ID Teste: 7 Data: 28/05/2013 Tipo de Teste: Teste às funcionalidade com Parsing de Projeto. Descrição: Parsing aos samples do Jboss. Resultado Parsing Esperado: Parsing a todos os ficheiros sem qualquer erro de parsing detetado. Resultado Parsing Obtido: Parsing de todos os ficheiros sem qualquer erro detetado. Output observado: t o t a l f i c h e i r o s : 197 F i c h e i r o s J a v a : 188 F i c h e i r o s JSP : 9 pasing completo : 197 Erro de p a r s i n g : 0 t o t a l de l i n h a s : 14742 Tempo t o t a l ( ms ) : 1012 mé d i a ( ms / l i n h a ) : 0.06864740198073531 Resultado do Teste: Pass. ID Teste: 8 Data: 28/05/2013 Tipo de Teste: Teste às funcionalidade com Parsing de Projeto. Descrição: Parsing ao projeto final da Cadeira de IS 2012/2013, contendo várias tecnologias JavaEE/J2EE. Resultado Parsing Esperado: Parsing a todos os ficheiros sem qualquer erro de parsing detetado. Resultado Parsing Obtido: Parsing de todos os ficheiros sem qualquer erro detetado. Output observado: t o t a l f i c h e i r o s : 62 F i c h e i r o s J a v a : 51 F i c h e i r o s JSP : 11 pasing completo : 62 Erro de p a r s i n g : 0 t o t a l de l i n h a s : 7197 Tempo t o t a l ( ms ) : 307 mé d i a ( ms / l i n h a ) : 0.042656662498263165 Resultado do Teste: Pass. lxxxiii Luís Laranjeira - PJMAS G.3 Testes de Integração Tester: Hugo Trovão ID Teste: 1 Data: 15/04/2013 Tipo de Teste: Teste de Integração. Compatibilidade com o CodeV: 90% Estimativa nós compatíveis: 95% Estimativa nós incompatíveis: 5% Observações: Resolução de objetos em nós compatíveis. Alguns nós novos terão de ser implementados no motor de análise pois pertencem a um conjunto que não existia nas linguagens anteriores. Ações Efetuadas: Laranjeira corrigiu os nós e o seu preenchimento com os objetos em falta. Foi implementada no motor de analise a interpretação dos novos nós. Tester: Hugo Trovão ID Teste: 2 Data: 05/06/2013 Tipo de Teste: Teste de Integração. Compatibilidade com o CodeV: 95% Estimativa nós compatíveis: 100% Estimativa nós incompatíveis: 0% Observações: Alguns nós mais específicos não são interpretados pelo motor de analise. Ações Efetuadas: De momento ainda não se vai fazer análise a certos casos específicos. lxxxiv