This file is indexed.

/usr/lib/python3/dist-packages/jsonpickle/unpickler.py is in python3-jsonpickle 0.6.1-1.

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
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
# -*- coding: utf-8 -*-
#
# Copyright (C) 2008 John Paulett (john -at- paulett.org)
# Copyright (C) 2009, 2011, 2013 David Aguilar (davvid -at- gmail.com)
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution.

import operator
import sys

import jsonpickle.util as util
import jsonpickle.tags as tags
import jsonpickle.handlers as handlers

from jsonpickle.compat import set
from jsonpickle.backend import JSONBackend


def decode(string, backend=None, context=None, keys=False, reset=True):
    backend = _make_backend(backend)
    if context is None:
        context = Unpickler(keys=keys, backend=backend)
    return context.restore(backend.decode(string), reset=reset)


def _make_backend(backend):
    if backend is None:
        return JSONBackend()
    else:
        return backend


class Unpickler(object):
    def __init__(self, backend=None, keys=False):
        ## The current recursion depth
        ## Maps reference names to object instances
        self.backend = _make_backend(backend)
        self.keys = keys

        self._namedict = {}
        ## The namestack grows whenever we recurse into a child object
        self._namestack = []

        ## Maps objects to their index in the _objs list
        self._obj_to_idx = {}
        self._objs = []

    def reset(self):
        """Resets the object's internal state.
        """
        self._namedict = {}
        self._namestack = []
        self._obj_to_idx = {}
        self._objs = []

    def restore(self, obj, reset=True):
        """Restores a flattened object to its original python state.

        Simply returns any of the basic builtin types

        >>> u = Unpickler()
        >>> u.restore('hello world')
        'hello world'
        >>> u.restore({'key': 'value'})
        {'key': 'value'}
        """
        if reset:
            self.reset()
        return self._restore(obj)

    def _restore(self, obj):
        if has_tag(obj, tags.ID):
            restore = self._restore_id
        elif has_tag(obj, tags.REF): # Backwards compatibility
            restore = self._restore_ref
        elif has_tag(obj, tags.TYPE):
            restore = self._restore_type
        elif has_tag(obj, tags.REPR): # Backwards compatibility
            restore = self._restore_repr
        elif has_tag(obj, tags.OBJECT):
            restore = self._restore_object
        elif util.is_list(obj):
            restore = self._restore_list
        elif has_tag(obj, tags.TUPLE):
            restore = self._restore_tuple
        elif has_tag(obj, tags.SET):
            restore = self._restore_set
        elif util.is_dictionary(obj):
            restore = self._restore_dict
        else:
            restore = lambda x: x
        return restore(obj)

    def _restore_id(self, obj):
        return self._objs[obj[tags.ID]]

    def _restore_ref(self, obj):
        return self._namedict.get(obj[tags.REF])

    def _restore_type(self, obj):
        typeref = loadclass(obj[tags.TYPE])
        if typeref is None:
            return obj
        return typeref

    def _restore_repr(self, obj):
        obj = loadrepr(obj[tags.REPR])
        return self._mkref(obj)

    def _restore_object(self, obj):
        cls = loadclass(obj[tags.OBJECT])
        if cls is None:
            return self._mkref(obj)
        handler = handlers.get(cls)
        if handler is not None: # custom handler
            instance = handler(self).restore(obj)
            return self._mkref(instance)
        else:
            return self._restore_object_instance(obj, cls)

    def _restore_object_instance(self, obj, cls):
        factory = loadfactory(obj)
        args = getargs(obj)
        if args:
            args = self._restore(args)
        try:
            if hasattr(cls, '__new__'): # new style classes
                if factory:
                    instance = cls.__new__(cls, factory, *args)
                    instance.default_factory = factory
                else:
                    instance = cls.__new__(cls, *args)
            else:
                instance = object.__new__(cls)
        except TypeError: # old-style classes
            try:
                instance = cls()
            except TypeError: # fail gracefully
                return self._mkref(obj)

        self._mkref(instance) # allow references in downstream objects
        if isinstance(instance, tuple):
            return instance

        return self._restore_object_instance_variables(obj, instance)

    def _restore_object_instance_variables(self, obj, instance):
        if hasattr(instance, '__setstate__') and has_tag(obj, tags.STATE):
            state = self._restore(obj[tags.STATE])
            instance.__setstate__(state)
            return instance

        for k, v in sorted(obj.items(), key=operator.itemgetter(0)):
            # ignore the reserved attribute
            if k in tags.RESERVED:
                continue
            self._namestack.append(k)
            # step into the namespace
            value = self._restore(v)
            if (util.is_noncomplex(instance) or
                    util.is_dictionary_subclass(instance)):
                instance[k] = value
            else:
                setattr(instance, k, value)
            # step out
            self._namestack.pop()

        # Handle list and set subclasses
        if has_tag(obj, tags.SEQ):
            if hasattr(instance, 'append'):
                for v in obj[tags.SEQ]:
                    instance.append(self._restore(v))
            if hasattr(instance, 'add'):
                for v in obj[tags.SEQ]:
                    instance.add(self._restore(v))

        return instance

    def _restore_list(self, obj):
        parent = []
        self._mkref(parent)
        children = [self._restore(v) for v in obj]
        parent.extend(children)
        return parent

    def _restore_tuple(self, obj):
        return tuple([self._restore(v) for v in obj[tags.TUPLE]])

    def _restore_set(self, obj):
        return set([self._restore(v) for v in obj[tags.SET]])

    def _restore_dict(self, obj):
        data = {}
        for k, v in sorted(obj.items(), key=operator.itemgetter(0)):
            self._namestack.append(k)
            if self.keys and k.startswith(tags.JSON_KEY):
                k = decode(k[len(tags.JSON_KEY):],
                           backend=self.backend, context=self,
                           keys=True, reset=False)
            data[k] = self._restore(v)
            self._namestack.pop()
        return data

    def _refname(self):
        """Calculates the name of the current location in the JSON stack.

        This is called as jsonpickle traverses the object structure to
        create references to previously-traversed objects.  This allows
        cyclical data structures such as doubly-linked lists.
        jsonpickle ensures that duplicate python references to the same
        object results in only a single JSON object definition and
        special reference tags to represent each reference.

        >>> u = Unpickler()
        >>> u._namestack = []
        >>> u._refname()
        '/'

        >>> u._namestack = ['a']
        >>> u._refname()
        '/a'

        >>> u._namestack = ['a', 'b']
        >>> u._refname()
        '/a/b'

        """
        return '/' + '/'.join(self._namestack)

    def _mkref(self, obj):
        """
        >>> from jsonpickle._samples import Thing
        >>> thing = Thing('referenced-thing')
        >>> u = Unpickler()
        >>> u._mkref(thing)
        Thing("referenced-thing")

        >>> u._objs[0]
        Thing("referenced-thing")

        """
        obj_id = id(obj)
        try:
            self._obj_to_idx[obj_id]
        except KeyError:
            self._obj_to_idx[obj_id] = len(self._objs)
            self._objs.append(obj)
            # Backwards compatibility: old versions of jsonpickle
            # produced "py/ref" references.
            self._namedict[self._refname()] = obj
        return obj


def loadclass(module_and_name):
    """Loads the module and returns the class.

    >>> loadclass('jsonpickle._samples.Thing')
    <class 'jsonpickle._samples.Thing'>

    >>> loadclass('does.not.exist')


    >>> loadclass('__builtin__.int')()
    0

    """
    try:
        module, name = module_and_name.rsplit('.', 1)
        module = util.untranslate_module_name(module)
        __import__(module)
        return getattr(sys.modules[module], name)
    except:
        return None


def loadfactory(obj):
    try:
        default_factory = obj['default_factory']
    except KeyError:
        return None
    try:
        type_tag = default_factory[tags.TYPE]
    except:
        return None

    typeref = loadclass(type_tag)
    if typeref:
        del obj['default_factory']
        return typeref

    return None


def getargs(obj):
    try:
        seq_list = obj[tags.SEQ]
        obj_dict = obj[tags.OBJECT]
    except KeyError:
        return []
    typeref = loadclass(obj_dict)
    if not typeref:
        return []
    if hasattr(typeref, '_fields'):
        if len(typeref._fields) == len(seq_list):
            return seq_list
    return []


def loadrepr(reprstr):
    """Returns an instance of the object from the object's repr() string.
    It involves the dynamic specification of code.

    >>> loadrepr('jsonpickle._samples/jsonpickle._samples.Thing("json")')
    Thing("json")

    """
    module, evalstr = reprstr.split('/')
    mylocals = locals()
    localname = module
    if '.' in localname:
        localname = module.split('.', 1)[0]
    mylocals[localname] = __import__(module)
    return eval(evalstr)


def has_tag(obj, tag):
    """Helper class that tests to see if the obj is a dictionary
    and contains a particular key/tag.

    >>> obj = {'test': 1}
    >>> has_tag(obj, 'test')
    True
    >>> has_tag(obj, 'fail')
    False

    >>> has_tag(42, 'fail')
    False

    """
    return type(obj) is dict and tag in obj