This file is indexed.

/usr/lib/python3/dist-packages/dcos/jsonitem.py is in python3-dcos 0.2.0-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
import collections
import json
import re

from dcos import util
from dcos.errors import DCOSException

logger = util.get_logger(__name__)


def parse_json_item(json_item, schema):
    """Parse the json item (optionally based on a schema).

    :param json_item: A JSON item in the form 'key=value'
    :type json_item: str
    :param schema: The JSON schema to use for parsing
    :type schema: dict
    :returns: A tuple for the parsed JSON item
    :rtype: (str, any) where any is one of str, int, float, bool, list or dict
    """

    terms = json_item.split('=', 1)
    if len(terms) != 2:
        raise DCOSException('{!r} is not a valid json-item'.format(json_item))

    # Check that it is a valid key in our jsonschema
    key = terms[0]

    # Use the schema if we have it else, guess the type
    if schema:
        value = parse_json_value(key, terms[1], schema)
    else:
        value = _find_type(clean_value(terms[1]))

    return (json.dumps(key), value)


def parse_json_value(key, value, schema):
    """Parse the json value based on a schema.

    :param key: the key property
    :type key: str
    :param value: the value of property
    :type value: str
    :param schema: The JSON schema to use for parsing
    :type schema: dict
    :returns: parsed value
    :rtype: str | int | float | bool | list | dict
    """

    value_type = find_parser(key, schema)
    return value_type(value)


def find_parser(key, schema):
    """
    :param key: JSON field
    :type key: str
    :param schema: The JSON schema to use
    :type schema: dict
    :returns: A callable capable of parsing a string to its type
    :rtype: ValueTypeParser
    """

    key_schema = schema['properties'].get(key)
    if key_schema is None:
        keys = ', '.join(schema['properties'].keys())
        raise DCOSException(
            'Error: {!r} is not a valid property. '
            'Possible properties are: {}'.format(key, keys))
    else:
        return ValueTypeParser(key_schema)


class ValueTypeParser(object):
    """Callable for parsing a string against a known JSON type.

    :param schema: The JSON type as a schema
    :type schema: dict
    """

    def __init__(self, schema):
        self.schema = schema

    def __call__(self, value):
        """
        :param value: String to try and parse
        :type value: str
        :returns: The parse value
        :rtype: str | int | float | bool | list | dict
        """

        value = clean_value(value)

        if self.schema['type'] == 'string':
            if self.schema.get('format') == 'uri':
                return _parse_url(value)
            else:
                return _parse_string(value)
        elif self.schema['type'] == 'object':
            return _parse_object(value)
        elif self.schema['type'] == 'number':
            return _parse_number(value)
        elif self.schema['type'] == 'integer':
            return _parse_integer(value)
        elif self.schema['type'] == 'boolean':
            return _parse_boolean(value)
        elif self.schema['type'] == 'array':
            return _parse_array(value)
        else:
            raise DCOSException('Unknown type {!r}'.format(self._value_type))


def clean_value(value):
    """
    :param value: String to try and clean
    :type value: str
    :returns: The cleaned string
    :rtype: str
    """

    if len(value) > 1 and value.startswith('"') and value.endswith('"'):
        return value[1:-1]
    elif len(value) > 1 and value.startswith("'") and value.endswith("'"):
        return value[1:-1]
    else:
        return value


def _find_type(value):
    """Find the correct type of the value

    :param value: value to parse
    :type value: str
    :returns: The parsed value
    :rtype: int|float|
    """
    to_try = [_parse_integer, _parse_number, _parse_boolean, _parse_array,
              _parse_url, _parse_object, _parse_string]
    while len(to_try) > 0:
        try:
            return to_try.pop(0)(value)
        except DCOSException:
            pass

    raise DCOSException(
        'Unable to parse {!r} as a JSON object'.format(value))


def _parse_string(value):
    """
    :param value: The string to parse
    :type value: str
    :returns: The parsed value
    :rtype: str
    """

    return None if value == 'null' else value


def _parse_object(value):
    """
    :param value: The string to parse
    :type value: str
    :returns: The parsed value
    :rtype: dict
    """

    try:
        json_object = json.loads(value)
        if json_object is None or isinstance(json_object, collections.Mapping):
            return json_object
        else:
            raise DCOSException(
                'Unable to parse {!r} as a JSON object'.format(value))
    except ValueError as error:
        logger.exception('Error parsing value as a JSON object')

        msg = 'Unable to parse {!r} as a JSON object: {}'.format(value, error)
        raise DCOSException(msg)


def _parse_number(value):
    """
    :param value: The string to parse
    :type value: str
    :returns: The parsed value
    :rtype: float
    """

    try:
        return None if value == 'null' else float(value)
    except ValueError as error:
        logger.exception('Error parsing value as a JSON number')

        msg = 'Unable to parse {!r} as a float: {}'.format(value, error)
        raise DCOSException(msg)


def _parse_integer(value):
    """
    :param value: The string to parse
    :type value: str
    :returns: The parsed value
    :rtype: int
    """

    try:
        return None if value == 'null' else int(value)
    except ValueError as error:
        logger.exception('Error parsing value as a JSON integer')

        msg = 'Unable to parse {!r} as an int: {}'.format(value, error)
        raise DCOSException(msg)


def _parse_boolean(value):
    """
    :param value: The string to parse
    :type value: str
    :returns: The parsed value
    :rtype: bool
    """

    try:
        boolean = json.loads(value)
        if boolean is None or isinstance(boolean, bool):
            return boolean
        else:
            raise DCOSException(
                'Unable to parse {!r} as a boolean'.format(value))
    except ValueError as error:
        logger.exception('Error parsing value as a JSON boolean')

        msg = 'Unable to parse {!r} as a boolean: {}'.format(value, error)
        raise DCOSException(msg)


def _parse_array(value):
    """
    :param value: The string to parse
    :type value: str
    :returns: The parsed value
    :rtype: list
    """

    try:
        array = json.loads(value)
        if array is None or isinstance(array, collections.Sequence):
            return array
        else:
            raise DCOSException(
                'Unable to parse {!r} as an array'.format(value))
    except ValueError as error:
        logger.exception('Error parsing value as a JSON array')

        msg = 'Unable to parse {!r} as an array: {}'.format(value, error)
        raise DCOSException(msg)


def _parse_url(value):
    """
    :param value: The url to parse
    :type url: str
    :returns: The parsed value
    :rtype: str
    """

    scheme_pattern = r'^(?P<scheme>(?:(?:https?)://))'
    domain_pattern = (
        r'(?P<hostname>(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.?)+'
        '(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)?|')  # domain,

    value_regex = re.match(
        scheme_pattern +  # http:// or https://
        r'(([^:])+(:[^:]+)?@){0,1}' +  # auth credentials
        domain_pattern +
        r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}))'  # or ip
        r'(?P<port>(?::\d+))?'  # port
        r'(?P<path>(?:/?|[/?]\S+))$',  # resource path
        value, re.IGNORECASE)

    if value_regex is None:
        scheme_match = re.match(scheme_pattern, value, re.IGNORECASE)
        if scheme_match is None:
            msg = 'Please check url {!r}. Missing http(s)://'.format(value)
            raise DCOSException(msg)
        else:
            raise DCOSException(
                'Unable to parse {!r} as a url'.format(value))
    else:
        return value