Stacktrace contains xml escaped characters. Fix #948, #981 (#996)

* Fix 948. Stacktrace contains xml escaped characters.

* Test for paht containing ampersand
This commit is contained in:
Karthik Nadig 2018-11-08 14:45:14 -08:00 committed by GitHub
parent 32169977bc
commit f3cfd0fb8a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 4 deletions

View file

@ -17,6 +17,7 @@ import socket
import sys
import threading
import traceback
try:
import urllib
urllib.unquote
@ -32,6 +33,7 @@ except ImportError:
import Queue as queue
import warnings
from xml.sax import SAXParseException
from xml.sax.saxutils import unescape as xml_unescape
import _pydevd_bundle.pydevd_comm as pydevd_comm # noqa
import _pydevd_bundle.pydevd_comm_constants as pydevd_comm_constants # noqa
@ -212,6 +214,15 @@ def unquote(s):
return urllib.unquote(s)
def unquote_xml_path(s):
"""XML unescape after url unquote. This reverses the escapes and quotes done
by pydevd.
"""
if s is None:
return None
return xml_unescape(unquote(str(s)))
class IDMap(object):
"""Maps VSCode entities to corresponding pydevd entities by ID.
@ -1686,7 +1697,7 @@ class VSCodeMessageProcessor(VSCLifecycleMsgProcessor):
fid = self.frame_map.to_vscode(key, autogen=True)
name = unquote(xframe['name'])
# pydevd encodes if necessary and then uses urllib.quote.
norm_path = self.path_casing.un_normcase(unquote(str(xframe['file']))) # noqa
norm_path = self.path_casing.un_normcase(unquote_xml_path(xframe['file'])) # noqa
source_reference = self.get_source_reference(norm_path)
if not self.internals_filter.is_internal_path(norm_path):
module = self.modules_mgr.add_or_get_from_path(norm_path)
@ -2253,7 +2264,7 @@ class VSCodeMessageProcessor(VSCLifecycleMsgProcessor):
xframes = list(xml.thread.frame)
frame_data = []
for f in xframes:
file_path = unquote(f['file'])
file_path = unquote_xml_path(f['file'])
if not self.internals_filter.is_internal_path(file_path) \
and self._should_debug(file_path):
line_no = int(f['line'])
@ -2270,7 +2281,7 @@ class VSCodeMessageProcessor(VSCLifecycleMsgProcessor):
func_name, None))
exc_stack = ''.join(traceback.format_list(frame_data))
exc_source = unquote(xframes[0]['file'])
exc_source = unquote_xml_path(xframes[0]['file'])
if self.internals_filter.is_internal_path(exc_source) or \
not self._should_debug(exc_source):
exc_source = None
@ -2471,7 +2482,7 @@ class VSCodeMessageProcessor(VSCLifecycleMsgProcessor):
# do step over and step out
xframes = list(xml.thread.frame)
xframe = xframes[0]
filepath = unquote(xframe['file'])
filepath = unquote_xml_path(xframe['file'])
if reason in STEP_REASONS or reason in EXCEPTION_REASONS:
if self.internals_filter.is_internal_path(filepath) or \
not self._should_debug(filepath):

View file

@ -0,0 +1,26 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See LICENSE in the project root
# for license information.
from __future__ import print_function, with_statement, absolute_import
import os.path
from pytests.helpers.timeline import Event
from ..helpers.pathutils import get_test_root, compare_path
BP_TEST_ROOT = get_test_root('bp')
def test_path_with_ampersand(debug_session):
bp_line = 2
testfile = os.path.join(BP_TEST_ROOT, 'a&b', 'test.py')
debug_session.common_setup(testfile, 'file', [bp_line])
debug_session.start_debugging()
hit = debug_session.wait_for_thread_stopped()
frames = hit.stacktrace.body['stackFrames']
assert compare_path(frames[0]['source']['path'], testfile)
debug_session.send_request('continue').wait_for_response()
debug_session.wait_for_next(Event('continued'))
debug_session.wait_for_exit()

View file

@ -0,0 +1,3 @@
print('one')
print('two')
print('three')