Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc90ff1b

Browse files
bpo-27863: Fixed multiple crashes in ElementTree. (#765) (#904)
(cherry picked from commit576def0)
1 parent0fadf25 commitc90ff1b

File tree

3 files changed

+167
-48
lines changed

3 files changed

+167
-48
lines changed

‎Lib/test/test_xml_etree.py‎

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1875,6 +1875,118 @@ def test_recursive_repr(self):
18751875
withself.assertRaises(RuntimeError):
18761876
repr(e)# Should not crash
18771877

1878+
deftest_element_get_text(self):
1879+
# Issue #27863
1880+
classX(str):
1881+
def__del__(self):
1882+
try:
1883+
elem.text
1884+
exceptNameError:
1885+
pass
1886+
1887+
b=ET.TreeBuilder()
1888+
b.start('tag', {})
1889+
b.data('ABCD')
1890+
b.data(X('EFGH'))
1891+
b.data('IJKL')
1892+
b.end('tag')
1893+
1894+
elem=b.close()
1895+
self.assertEqual(elem.text,'ABCDEFGHIJKL')
1896+
1897+
deftest_element_get_tail(self):
1898+
# Issue #27863
1899+
classX(str):
1900+
def__del__(self):
1901+
try:
1902+
elem[0].tail
1903+
exceptNameError:
1904+
pass
1905+
1906+
b=ET.TreeBuilder()
1907+
b.start('root', {})
1908+
b.start('tag', {})
1909+
b.end('tag')
1910+
b.data('ABCD')
1911+
b.data(X('EFGH'))
1912+
b.data('IJKL')
1913+
b.end('root')
1914+
1915+
elem=b.close()
1916+
self.assertEqual(elem[0].tail,'ABCDEFGHIJKL')
1917+
1918+
deftest_element_iter(self):
1919+
# Issue #27863
1920+
state= {
1921+
'tag':'tag',
1922+
'_children': [None],# non-Element
1923+
'attrib':'attr',
1924+
'tail':'tail',
1925+
'text':'text',
1926+
}
1927+
1928+
e=ET.Element('tag')
1929+
try:
1930+
e.__setstate__(state)
1931+
exceptAttributeError:
1932+
e.__dict__=state
1933+
1934+
it=e.iter()
1935+
self.assertIs(next(it),e)
1936+
self.assertRaises(AttributeError,next,it)
1937+
1938+
deftest_subscr(self):
1939+
# Issue #27863
1940+
classX:
1941+
def__index__(self):
1942+
dele[:]
1943+
return1
1944+
1945+
e=ET.Element('elem')
1946+
e.append(ET.Element('child'))
1947+
e[:X()]# shouldn't crash
1948+
1949+
e.append(ET.Element('child'))
1950+
e[0:10:X()]# shouldn't crash
1951+
1952+
deftest_ass_subscr(self):
1953+
# Issue #27863
1954+
classX:
1955+
def__index__(self):
1956+
e[:]= []
1957+
return1
1958+
1959+
e=ET.Element('elem')
1960+
for_inrange(10):
1961+
e.insert(0,ET.Element('child'))
1962+
1963+
e[0:10:X()]= []# shouldn't crash
1964+
1965+
deftest_treebuilder_start(self):
1966+
# Issue #27863
1967+
defelement_factory(x,y):
1968+
return []
1969+
b=ET.TreeBuilder(element_factory=element_factory)
1970+
1971+
b.start('tag', {})
1972+
b.data('ABCD')
1973+
self.assertRaises(AttributeError,b.start,'tag2', {})
1974+
delb
1975+
gc_collect()
1976+
1977+
deftest_treebuilder_end(self):
1978+
# Issue #27863
1979+
defelement_factory(x,y):
1980+
return []
1981+
b=ET.TreeBuilder(element_factory=element_factory)
1982+
1983+
b.start('tag', {})
1984+
b.data('ABCD')
1985+
self.assertRaises(AttributeError,b.end,'tag')
1986+
delb
1987+
gc_collect()
1988+
1989+
18781990
classMutatingElementPath(str):
18791991
def__new__(cls,elem,*args):
18801992
self=str.__new__(cls,*args)

‎Misc/NEWS‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ Extension Modules
4646
Library
4747
-------
4848

49+
- bpo-27863: Fixed multiple crashes in ElementTree caused by race conditions
50+
and wrong types.
51+
4952
- bpo-28699: Fixed a bug in pools in multiprocessing.pool that raising an
5053
exception at the very first of an iterable may swallow the exception or
5154
make the program hang. Patch by Davin Potts and Xiang Zhang.

‎Modules/_elementtree.c‎

Lines changed: 52 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ deepcopy(PyObject* object, PyObject* memo)
155155
LOCAL(PyObject*)
156156
list_join(PyObject*list)
157157
{
158-
/* join list elements(destroying the list in the process)*/
158+
/* join list elements */
159159
PyObject*joiner;
160160
PyObject*result;
161161

@@ -164,8 +164,6 @@ list_join(PyObject* list)
164164
returnNULL;
165165
result=PyUnicode_Join(joiner,list);
166166
Py_DECREF(joiner);
167-
if (result)
168-
Py_DECREF(list);
169167
returnresult;
170168
}
171169

@@ -534,15 +532,17 @@ element_get_text(ElementObject* self)
534532
{
535533
/* return borrowed reference to text attribute */
536534

537-
PyObject*res=self->text;
535+
PyObject*res=self->text;
538536

539537
if (JOIN_GET(res)) {
540538
res=JOIN_OBJ(res);
541539
if (PyList_CheckExact(res)) {
542-
res=list_join(res);
543-
if (!res)
540+
PyObject*tmp=list_join(res);
541+
if (!tmp)
544542
returnNULL;
545-
self->text=res;
543+
self->text=tmp;
544+
Py_DECREF(res);
545+
res=tmp;
546546
}
547547
}
548548

@@ -554,15 +554,17 @@ element_get_tail(ElementObject* self)
554554
{
555555
/* return borrowed reference to text attribute */
556556

557-
PyObject*res=self->tail;
557+
PyObject*res=self->tail;
558558

559559
if (JOIN_GET(res)) {
560560
res=JOIN_OBJ(res);
561561
if (PyList_CheckExact(res)) {
562-
res=list_join(res);
563-
if (!res)
562+
PyObject*tmp=list_join(res);
563+
if (!tmp)
564564
returnNULL;
565-
self->tail=res;
565+
self->tail=tmp;
566+
Py_DECREF(res);
567+
res=tmp;
566568
}
567569
}
568570

@@ -2147,6 +2149,12 @@ elementiter_next(ElementIterObject *it)
21472149
cur_parent=it->parent_stack->parent;
21482150
child_index=it->parent_stack->child_index;
21492151
if (cur_parent->extra&&child_index<cur_parent->extra->length) {
2152+
if (!PyObject_TypeCheck(cur_parent->extra->children[child_index],&Element_Type)) {
2153+
PyErr_Format(PyExc_AttributeError,
2154+
"'%.100s' object has no attribute 'iter'",
2155+
Py_TYPE(cur_parent->extra->children[child_index])->tp_name);
2156+
returnNULL;
2157+
}
21502158
elem= (ElementObject*)cur_parent->extra->children[child_index];
21512159
it->parent_stack->child_index++;
21522160
it->parent_stack=parent_stack_push_new(it->parent_stack,
@@ -2435,40 +2443,51 @@ treebuilder_dealloc(TreeBuilderObject *self)
24352443
/* helpers for handling of arbitrary element-like objects */
24362444

24372445
staticint
2438-
treebuilder_set_element_text_or_tail(PyObject*element,PyObject*data,
2446+
treebuilder_set_element_text_or_tail(PyObject*element,PyObject**data,
24392447
PyObject**dest,_Py_Identifier*name)
24402448
{
24412449
if (Element_CheckExact(element)) {
2442-
Py_DECREF(JOIN_OBJ(*dest));
2443-
*dest=JOIN_SET(data,PyList_CheckExact(data));
2450+
PyObject*tmp=JOIN_OBJ(*dest);
2451+
*dest=JOIN_SET(*data,PyList_CheckExact(*data));
2452+
*data=NULL;
2453+
Py_DECREF(tmp);
24442454
return0;
24452455
}
24462456
else {
2447-
PyObject*joined=list_join(data);
2457+
PyObject*joined=list_join(*data);
24482458
intr;
24492459
if (joined==NULL)
24502460
return-1;
24512461
r=_PyObject_SetAttrId(element,name,joined);
24522462
Py_DECREF(joined);
2453-
returnr;
2463+
if (r<0)
2464+
return-1;
2465+
Py_CLEAR(*data);
2466+
return0;
24542467
}
24552468
}
24562469

2457-
/* These two functions steal a reference to data */
2458-
staticint
2459-
treebuilder_set_element_text(PyObject*element,PyObject*data)
2470+
LOCAL(int)
2471+
treebuilder_flush_data(TreeBuilderObject*self)
24602472
{
2461-
_Py_IDENTIFIER(text);
2462-
returntreebuilder_set_element_text_or_tail(
2463-
element,data,&((ElementObject*)element)->text,&PyId_text);
2464-
}
2473+
PyObject*element=self->last;
24652474

2466-
staticint
2467-
treebuilder_set_element_tail(PyObject*element,PyObject*data)
2468-
{
2469-
_Py_IDENTIFIER(tail);
2470-
returntreebuilder_set_element_text_or_tail(
2471-
element,data,&((ElementObject*)element)->tail,&PyId_tail);
2475+
if (!self->data) {
2476+
return0;
2477+
}
2478+
2479+
if (self->this==element) {
2480+
_Py_IDENTIFIER(text);
2481+
returntreebuilder_set_element_text_or_tail(
2482+
element,&self->data,
2483+
&((ElementObject*)element)->text,&PyId_text);
2484+
}
2485+
else {
2486+
_Py_IDENTIFIER(tail);
2487+
returntreebuilder_set_element_text_or_tail(
2488+
element,&self->data,
2489+
&((ElementObject*)element)->tail,&PyId_tail);
2490+
}
24722491
}
24732492

24742493
staticint
@@ -2517,16 +2536,8 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag,
25172536
PyObject*this;
25182537
elementtreestate*st=ET_STATE_GLOBAL;
25192538

2520-
if (self->data) {
2521-
if (self->this==self->last) {
2522-
if (treebuilder_set_element_text(self->last,self->data))
2523-
returnNULL;
2524-
}
2525-
else {
2526-
if (treebuilder_set_element_tail(self->last,self->data))
2527-
returnNULL;
2528-
}
2529-
self->data=NULL;
2539+
if (treebuilder_flush_data(self)<0) {
2540+
returnNULL;
25302541
}
25312542

25322543
if (self->element_factory&&self->element_factory!=Py_None) {
@@ -2622,15 +2633,8 @@ treebuilder_handle_end(TreeBuilderObject* self, PyObject* tag)
26222633
{
26232634
PyObject*item;
26242635

2625-
if (self->data) {
2626-
if (self->this==self->last) {
2627-
if (treebuilder_set_element_text(self->last,self->data))
2628-
returnNULL;
2629-
}else {
2630-
if (treebuilder_set_element_tail(self->last,self->data))
2631-
returnNULL;
2632-
}
2633-
self->data=NULL;
2636+
if (treebuilder_flush_data(self)<0) {
2637+
returnNULL;
26342638
}
26352639

26362640
if (self->index==0) {

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2026 Movatter.jp