Source code for cpe.comp.cpecomp2_3

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
This file is part of cpe package.

This module allows to store the value of the components of a CPE name
of version 2.3 of CPE (Common Platform Enumeration) specification.

Copyright (C) 2013  Alejandro Galindo García, Roberto Abdelkader Martínez Pérez

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

For any problems using the cpe package, or general questions and
feedback about it, please contact:

- Alejandro Galindo García: galindo.garcia.alejandro@gmail.com
- Roberto Abdelkader Martínez Pérez: robertomartinezp@gmail.com
"""

from cpecomp_simple import CPEComponentSimple

import re


[docs]class CPEComponent2_3(CPEComponentSimple): """ Represents a component of version 2.3 of CPE specification. """ #################### # OBJECT METHODS # ####################
[docs] def __repr__(self): """ Returns a unambiguous representation of CPE component. :returns: Representation of CPE component as string :rtype: string """ value = self.get_value() return "{0}({1})".format(self.__class__.__name__, value)
def _is_valid_language(self): """ Return True if the value of component in attribute "language" is valid, and otherwise False. :returns: True if value is valid, False otherwise :rtype: boolean CASE 1: Language part with/without region part CASE 2: Language part without region part CASE 3: Region part with language part CASE 4: Region part without language part """ def check_generic_language(self, value): """ Check possible values in language part when region part exists or not in language value. Possible values of language attribute: a=letter | *a | *aa | aa | aaa | ?a | ?aa | ?? | ??a | ??? """ lang_pattern = [] lang_pattern.append("^(\\") lang_pattern.append(self.WILDCARD_MULTI) lang_pattern.append("[a-z]{1,2}") lang_pattern.append("|\\") lang_pattern.append(self.WILDCARD_ONE) lang_pattern.append("(([a-z][a-z]?)|(\\") lang_pattern.append(self.WILDCARD_ONE) lang_pattern.append("(\\") lang_pattern.append(self.WILDCARD_ONE) lang_pattern.append("|[a-z])?))") lang_pattern.append("|([a-z]{2,3}))$") lang_rxc = re.compile("".join(lang_pattern)) return lang_rxc.match(value) def check_language_without_region(self, value): """ Check possible values in language part when region part not exist in language value. Possible values of language attribute: a=letter | a? | aa? | a?? | a* | aa* | aaa* | *a* | *a? | ?a* | ?a? """ lang_pattern = [] lang_pattern.append("^([a-z]") lang_pattern.append("([a-z](\\") lang_pattern.append(self.WILDCARD_MULTI) lang_pattern.append("|\\") lang_pattern.append(self.WILDCARD_ONE) lang_pattern.append("|") lang_pattern.append("([a-z]\\") lang_pattern.append(self.WILDCARD_MULTI) lang_pattern.append("))") lang_pattern.append("|") lang_pattern.append("\\") lang_pattern.append(self.WILDCARD_ONE) lang_pattern.append("(\\") lang_pattern.append(self.WILDCARD_ONE) lang_pattern.append(")?") lang_pattern.append("|\\") lang_pattern.append(self.WILDCARD_MULTI) lang_pattern.append(")|\\") lang_pattern.append(self.WILDCARD_ONE) lang_pattern.append("[a-z](\\") lang_pattern.append(self.WILDCARD_MULTI) lang_pattern.append("|\\") lang_pattern.append(self.WILDCARD_ONE) lang_pattern.append(")") lang_pattern.append("|\\") lang_pattern.append(self.WILDCARD_MULTI) lang_pattern.append("[a-z](\\") lang_pattern.append(self.WILDCARD_MULTI) lang_pattern.append("|\\") lang_pattern.append(self.WILDCARD_ONE) lang_pattern.append(")") lang_pattern.append(")$") lang_rxc = re.compile("".join(lang_pattern)) return lang_rxc.match(value) def check_region_with_language(self, value): """ Check possible values in region part when language part exists. Possible values of language attribute: a=letter, 1=digit | * | a* | a? | aa | ?? | 1* | 1?? | 11* | 11? | 111 | ??? """ region_pattern = [] region_pattern.append("^(") region_pattern.append("(\\") region_pattern.append(self.WILDCARD_MULTI) region_pattern.append(")|((\\") region_pattern.append(self.WILDCARD_ONE) region_pattern.append("){2,3})|([a-z]([a-z]|\\") region_pattern.append(self.WILDCARD_MULTI) region_pattern.append("|\\") region_pattern.append(self.WILDCARD_ONE) region_pattern.append("))|([0-9](\\") region_pattern.append(self.WILDCARD_MULTI) region_pattern.append("|\\") region_pattern.append(self.WILDCARD_ONE) region_pattern.append("(\\") region_pattern.append(self.WILDCARD_ONE) region_pattern.append(")?|[0-9][0-9\\") region_pattern.append(self.WILDCARD_MULTI) region_pattern.append("\\") region_pattern.append(self.WILDCARD_ONE) region_pattern.append("])))$") region_rxc = re.compile("".join(region_pattern)) return region_rxc.match(region) def check_region_without_language(self, value): """ Check possible values in region part when language part not exist. Possible values of language attribute: 1=digit | *111 | *11 | *1 """ region_pattern = [] region_pattern.append("^(") region_pattern.append("(\\") region_pattern.append(self.WILDCARD_MULTI) region_pattern.append("[0-9])") region_pattern.append("([0-9]([0-9])?)?") region_pattern.append(")$") region_rxc = re.compile("".join(region_pattern)) return region_rxc.match(region) comp_str = self._encoded_value.lower() # Value with wildcards; separate language and region of value parts = comp_str.split(self.SEPARATOR_LANG) language = parts[0] region_exists = len(parts) == 2 # Check the language part if check_generic_language(self, language) is not None: # Valid language, check region part if region_exists: # Region part exists; check it region = parts[1] return (check_region_with_language(self, region) is not None) else: # Not region part return True elif check_language_without_region(self, language) is not None: # Language without region; region part should not exist return not region_exists else: # Language part not exist; check region part region = parts[0] return check_region_without_language(self, region) is not None def _is_valid_part(self): """ Return True if the value of component in attribute "part" is valid, and otherwise False. :returns: True if value of component is valid, False otherwise :rtype: boolean """ comp_str = self._encoded_value # Check if value of component do not have wildcard if ((comp_str.find(self.WILDCARD_ONE) == -1) and (comp_str.find(self.WILDCARD_MULTI) == -1)): return super(CPEComponent2_3, self)._is_valid_part() # Compilation of regular expression associated with value of part part_pattern = "^(\{0}|\{1})$".format(self.WILDCARD_ONE, self.WILDCARD_MULTI) part_rxc = re.compile(part_pattern) return part_rxc.match(comp_str) is not None