This file is indexed.

/usr/lib/python2.7/dist-packages/keysign/gtkexcepthook.py is in gnome-keysign 0.9-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
#!/usr/bin/env python
# (c) 2003 Gustavo J A M Carneiro gjc at inescporto.pt
#     2004-2005 Filip Van Raemdonck
#
# http://www.daa.com.au/pipermail/pygtk/2003-August/005775.html
# Message-ID: <1062087716.1196.5.camel@emperor.homelinux.net>
#     "The license is whatever you want."
#
# This file was downloaded from http://www.sysfs.be/downloads/
# Adaptions 2009-2010 by Martin Renold:
# - let KeyboardInterrupt through
# - print traceback to stderr before showing the dialog
# - nonzero exit code when hitting the "quit" button
# - suppress more dialogs while one is already active
# - fix Details button when a context in the traceback is None
# - remove email features
# - fix lockup with dialog.run(), return to mainloop instead
# see also http://faq.pygtk.org/index.py?req=show&file=faq20.010.htp
# (The license is still whatever you want.)
from __future__ import print_function

import inspect
import linecache
import pydoc
import sys
import traceback
if sys.version_info.major < 3:
    from io import BytesIO as StringIO
else:
    from io import StringIO as StringIO
from gettext import gettext as _
import os

try:
    from urllib.parse import quote_plus
except ImportError:
    from urllib import quote_plus
import textwrap

from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import Pango

#with open(os.path.join(os.path.dirname(os.path.abspath(__file__)),
#                       '_version.py')) as f:
#    # This should define __version__
#    exec(f.read())
#VERSION = __version__
# We are ignoring the actual version for now, because it's only used
# to determine whether it's a -dev version to then show a "report"
# button. Let's show this button unconditionally for now.
# Once it's too annoying, we get rid of it.
VERSION = "0.0.0.1-dev"

# Function that will be called when the user presses "Quit"
# Return True to confirm quit, False to cancel
quit_confirmation_func = None

RESPONSE_QUIT = 1
RESPONSE_SEARCH = 2
RESPONSE_REPORT = 3

def analyse_simple(exctyp, value, tb):
    trace = StringIO()
    traceback.print_exception(exctyp, value, tb, None, trace)
    return trace


def lookup(name, frame, lcls):
    '''Find the value for a given name in the given frame'''
    if name in lcls:
        return 'local', lcls[name]
    elif name in frame.f_globals:
        return 'global', frame.f_globals[name]
    elif '__builtins__' in frame.f_globals:
        builtins = frame.f_globals['__builtins__']
        if type(builtins) is dict:
            if name in builtins:
                return 'builtin', builtins[name]
        else:
            if hasattr(builtins, name):
                return 'builtin', getattr(builtins, name)
    return None, []


def analyse(exctyp, value, tb):
    import tokenize
    import keyword
    import platform
    #import application

    #app = application.get_app()

    trace = StringIO()
    nlines = 3
    frecs = inspect.getinnerframes(tb, nlines)

    #trace.write('GNOME Keysign version: %s\n' % app.version)
    trace.write('System information: %s\n' % platform.platform())
    trace.write('Python information: %s\n' % sys.version)
    #trace.write('Using: %s\n' % (get_libs_version_string(),))

    trace.write('Traceback (most recent call last):\n')
    for frame, fname, lineno, funcname, context, cindex in frecs:
        trace.write('  File "%s", line %d, ' % (fname, lineno))
        args, varargs, varkw, lcls = inspect.getargvalues(frame)

        def readline(lno=[lineno], *args):
            if args:
                print(args)

            try:
                return linecache.getline(fname, lno[0])
            finally:
                lno[0] += 1
        all, prev, name, scope = {}, None, '', None
        for ttype, tstr, stup, etup, line in tokenize.generate_tokens(readline):
            if ttype == tokenize.NAME and tstr not in keyword.kwlist:
                if name:
                    if name[-1] == '.':
                        try:
                            val = getattr(prev, tstr)
                        except AttributeError:
                            # XXX skip the rest of this identifier only
                            break
                        name += tstr
                else:
                    assert not name and not scope
                    scope, val = lookup(tstr, frame, lcls)
                    name = tstr
                if val is not None:
                    prev = val
            elif tstr == '.':
                if prev:
                    name += '.'
            else:
                if name:
                    all[name] = (scope, prev)
                prev, name, scope = None, '', None
                if ttype == tokenize.NEWLINE:
                    break

        try:
            details = inspect.formatargvalues(args, varargs, varkw, lcls, formatvalue=lambda v: '=' + pydoc.text.repr(v))
        except:
            # seen that one on Windows (actual exception was KeyError: self)
            details = '(no details)'
        trace.write(funcname + details + '\n')
        if context is None:
            context = ['<source context missing>\n']
        trace.write(''.join(['    ' + x.replace('\t', '  ') for x in filter(lambda a: a.strip(), context)]))
        if len(all):
            trace.write('  variables: %s\n' % str(all))

    trace.write('%s: %s' % (exctyp.__name__, value))
    return trace


def _info(exctyp, value, tb):
    global exception_dialog_active
    if exctyp is KeyboardInterrupt:
        return original_excepthook(exctyp, value, tb)
    sys.stderr.write(analyse_simple(exctyp, value, tb).getvalue())
    if exception_dialog_active:
        return

    Gdk.pointer_ungrab(Gdk.CURRENT_TIME)
    Gdk.keyboard_ungrab(Gdk.CURRENT_TIME)

    exception_dialog_active = True
    # Create the dialog
    dialog = Gtk.MessageDialog(type=Gtk.MessageType.WARNING)
    dialog.set_title(_("Bug Detected"))

    primary = _(
        "<big><b>A programming error has been detected.</b></big>"
    )
    secondary = _(
        "You may be able to ignore this error and carry on working, "
        "but you may get unexpected results.\n\n"
        "Please tell the developers about this using the issue tracker "
        "if no-one else has reported it yet."
    )
    dialog.set_markup(primary)
    dialog.format_secondary_text(secondary)

    dialog.add_button(_("Search Tracker..."), RESPONSE_SEARCH)
    if "-" in VERSION:  # only development and prereleases
        dialog.add_button(_("Report..."), RESPONSE_REPORT)
        dialog.set_response_sensitive(RESPONSE_REPORT, False)
    dialog.add_button(_("Ignore Error"), Gtk.ResponseType.CLOSE)
    dialog.add_button(_("Quit GNOME Keysign"), RESPONSE_QUIT)

    # Add an expander with details of the problem to the dialog
    def expander_cb(expander, *ignore):
        # Ensures that on deactivating the expander, the dialog is resized down
        if expander.get_expanded():
            dialog.set_resizable(True)
        else:
            dialog.set_resizable(False)
    details_expander = Gtk.Expander()
    details_expander.set_label(_("Details..."))
    details_expander.connect("notify::expanded", expander_cb)

    textview = Gtk.TextView()
    textview.show()
    textview.set_editable(False)
    textview.modify_font(Pango.FontDescription("Monospace normal"))

    sw = Gtk.ScrolledWindow()
    sw.show()
    sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
    sw.add(textview)

    # Set window sizing so that it's always at least 600 pixels wide, and
    # increases by 300 pixels in height once the details panel is open
    sw.set_size_request(0, 300)
    dialog.set_size_request(600, 0)

    details_expander.add(sw)
    details_expander.show_all()
    dialog.get_content_area().pack_start(details_expander, True, True, 0)

    # Get the traceback and set contents of the details
    try:
        trace = analyse(exctyp, value, tb).getvalue()
    except:
        try:
            trace = _("Exception while analyzing the exception.") + "\n"
            trace += analyse_simple(exctyp, value, tb).getvalue()
        except:
            trace = _("Exception while analyzing the exception.")
    buf = textview.get_buffer()
    trace = "\n".join(["```python", trace, "```"])
    buf.set_text(trace)
    ## Would be nice to scroll to the bottom automatically, but @#&%*@
    #first, last = buf.get_bounds()
    #buf.place_cursor(last)
    #mark = buf.get_insert()
    ##buf.scroll_mark_onscreen()
    ##textview.scroll_mark_onscreen(buf.get_insert(), 0)
    #textview.scroll_to_mark(mark, 0.0)

    # Connect callback and present the dialog
    dialog.connect('response', _dialog_response_cb, trace, exctyp, value)
    #dialog.set_modal(True) # this might actually be contra-productive...
    dialog.show()
    # calling dialog.run() here locks everything up in some cases, so
    # we just return to the main loop instead


def _dialog_response_cb(dialog, resp, trace, exctyp, value):
    global exception_dialog_active

    if resp == RESPONSE_QUIT:
        if not quit_confirmation_func:
            sys.exit(1)  # Exit code is important for IDEs
        else:
            if quit_confirmation_func():
                sys.exit(1)  # Exit code is important for IDEs
            else:
                dialog.destroy()
                exception_dialog_active = False
    elif resp == RESPONSE_SEARCH:
        search_url = (
            "https://github.com/GNOME-Keysign/gnome-keysign/search"
            "?utf8=%E2%9C%93"
            "&q={}+{}"
            "&type=Issues"
        ).format(
            quote_plus(exctyp.__name__, "/"),
            quote_plus(str(value), "/")
        )
        Gtk.show_uri(None, search_url, Gdk.CURRENT_TIME)
        if "-" in VERSION:
            dialog.set_response_sensitive(RESPONSE_REPORT, True)
    elif resp == RESPONSE_REPORT:
        #TRANSLATORS: Crash report template for github, preceding a traceback.
        #TRANSLATORS: Please ask users kindly to supply at least an English
        #TRANSLATORS: title if they are able.
        body = _(u"""\
            #### Description

            Give this report a short descriptive title.
            Use something like
            "{feature-that-broke}: {what-went-wrong}"
            for the title, if you can.
            Then please replace this text
            with a longer description of the bug.
            Screenshots or videos are great, too!

            #### Steps to reproduce

            Please tell us what you were doing
            when the error message popped up.
            If you can provide step-by-step instructions
            on how to reproduce the bug,
            that's even better.

            #### Traceback
        """)
        body = "\n\n".join([
            "".join(textwrap.wrap(p, sys.maxsize))
            for p in textwrap.dedent(body).split("\n\n")
        ] + [trace])
        report_url = (
            "https://github.com/GNOME-Keysign/gnome-keysign/issues/new"
            "?title={title}"
            "&body={body}"
        ).format(
            title="",
            body=quote_plus(body.encode("utf-8"), "/"),
        )
        Gtk.show_uri(None, report_url, Gdk.CURRENT_TIME)
    else:
        dialog.destroy()
        exception_dialog_active = False


original_excepthook = sys.excepthook
sys.excepthook = _info
exception_dialog_active = False


if __name__ == '__main__':
    import sys
    import os

    def _test_button_clicked_cb(*a):
        class _TestException (Exception):
            pass
        raise _TestException("That was supposed to happen.")

    win = Gtk.Window()
    win.set_size_request(200, 150)
    win.set_title(os.path.basename(sys.argv[0]))
    btn = Gtk.Button("Break it")
    btn.connect("clicked", _test_button_clicked_cb)
    win.add(btn)
    win.connect("destroy", lambda *a: Gtk.main_quit())
    win.show_all()
    Gtk.main()