| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 # Copyright (C) 2013 Google Inc. All rights reserved. |  | 
| 2 # |  | 
| 3 # Redistribution and use in source and binary forms, with or without |  | 
| 4 # modification, are permitted provided that the following conditions are |  | 
| 5 # met: |  | 
| 6 # |  | 
| 7 #     * Redistributions of source code must retain the above copyright |  | 
| 8 # notice, this list of conditions and the following disclaimer. |  | 
| 9 #     * Redistributions in binary form must reproduce the above |  | 
| 10 # copyright notice, this list of conditions and the following disclaimer |  | 
| 11 # in the documentation and/or other materials provided with the |  | 
| 12 # distribution. |  | 
| 13 #     * Neither the name of Google Inc. nor the names of its |  | 
| 14 # contributors may be used to endorse or promote products derived from |  | 
| 15 # this software without specific prior written permission. |  | 
| 16 # |  | 
| 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |  | 
| 18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |  | 
| 19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |  | 
| 20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |  | 
| 21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |  | 
| 22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |  | 
| 23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |  | 
| 24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |  | 
| 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |  | 
| 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |  | 
| 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |  | 
| 28 |  | 
| 29 """Validate extended attributes.""" |  | 
| 30 |  | 
| 31 |  | 
| 32 import re |  | 
| 33 |  | 
| 34 |  | 
| 35 class IDLInvalidExtendedAttributeError(Exception): |  | 
| 36     pass |  | 
| 37 |  | 
| 38 |  | 
| 39 class IDLExtendedAttributeValidator(object): |  | 
| 40     def __init__(self, extended_attributes_filename): |  | 
| 41         self.valid_extended_attributes = read_extended_attributes_file(extended_
    attributes_filename) |  | 
| 42 |  | 
| 43     def validate_extended_attributes(self, definitions): |  | 
| 44         # FIXME: this should be done when parsing the file, rather than after. |  | 
| 45         for interface in definitions.interfaces.itervalues(): |  | 
| 46             self.validate_extended_attributes_node(interface) |  | 
| 47             for attribute in interface.attributes: |  | 
| 48                 self.validate_extended_attributes_node(attribute) |  | 
| 49             for operation in interface.operations: |  | 
| 50                 self.validate_extended_attributes_node(operation) |  | 
| 51                 for argument in operation.arguments: |  | 
| 52                     self.validate_extended_attributes_node(argument) |  | 
| 53 |  | 
| 54     def validate_extended_attributes_node(self, node): |  | 
| 55         for name, values_string in node.extended_attributes.iteritems(): |  | 
| 56             self.validate_name_values_string(name, values_string) |  | 
| 57 |  | 
| 58     def validate_name_values_string(self, name, values_string): |  | 
| 59         if name == 'ImplementedBy':  # attribute added when merging interfaces |  | 
| 60             return |  | 
| 61         if name not in self.valid_extended_attributes: |  | 
| 62             raise IDLInvalidExtendedAttributeError('Unknown extended attribute [
    %s]' % name) |  | 
| 63         valid_values = self.valid_extended_attributes[name] |  | 
| 64         if values_string is None and None not in valid_values: |  | 
| 65             raise IDLInvalidExtendedAttributeError('Missing required argument fo
    r extended attribute [%s]' % name) |  | 
| 66         if '*' in valid_values:  # wildcard, any (non-empty) value ok |  | 
| 67             return |  | 
| 68         if values_string is None: |  | 
| 69             values = set([None]) |  | 
| 70         else: |  | 
| 71             values = set(re.split('[|&]', values_string)) |  | 
| 72         invalid_values = values - valid_values |  | 
| 73         if invalid_values: |  | 
| 74             invalid_value = invalid_values.pop() |  | 
| 75             raise IDLInvalidExtendedAttributeError('Invalid value "%s" found in 
    extended attribute [%s=%s]' % (invalid_value, name, values_string)) |  | 
| 76 |  | 
| 77 |  | 
| 78 def read_extended_attributes_file(extended_attributes_filename): |  | 
| 79     def extended_attribute_name_values(): |  | 
| 80         with open(extended_attributes_filename) as extended_attributes_file: |  | 
| 81             for line in extended_attributes_file: |  | 
| 82                 line = line.strip() |  | 
| 83                 if not line or line.startswith('#'): |  | 
| 84                     continue |  | 
| 85                 name, _, values_string = map(str.strip, line.partition('=')) |  | 
| 86                 value_list = [value.strip() for value in values_string.split('|'
    )] |  | 
| 87                 yield name, value_list |  | 
| 88 |  | 
| 89     valid_extended_attributes = {} |  | 
| 90     for name, value_list in extended_attribute_name_values(): |  | 
| 91         if not value_list: |  | 
| 92             valid_extended_attributes[name] = set([None]) |  | 
| 93             continue |  | 
| 94         valid_extended_attributes[name] = set([value if value else None |  | 
| 95                                                for value in value_list]) |  | 
| 96     return valid_extended_attributes |  | 
| OLD | NEW | 
|---|