Skip to content

Commit 7a869ed

Browse files
Merge branch 'philippe/fix-320-changes' into philippe/fix-320
2 parents 9689244 + f27780d commit 7a869ed

File tree

7 files changed

+80
-28
lines changed

7 files changed

+80
-28
lines changed

src/JSArrayProxy.cc

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -456,28 +456,37 @@ PyObject *JSArrayProxyMethodDefinitions::JSArrayProxy_richcompare(JSArrayProxy *
456456

457457
PyObject *leftItem = pyTypeFactory(GLOBAL_CX, elementVal);
458458
PyObject *rightItem;
459+
460+
bool needToDecRefRightItem;
459461
if (PyObject_TypeCheck(other, &JSArrayProxyType)) {
460462
JS_GetElement(GLOBAL_CX, *(((JSArrayProxy *)other)->jsArray), index, &elementVal);
461463
rightItem = pyTypeFactory(GLOBAL_CX, elementVal);
464+
needToDecRefRightItem = true;
462465
} else {
463466
rightItem = ((PyListObject *)other)->ob_item[index];
467+
needToDecRefRightItem = false;
464468
}
465469

466470
if (leftItem == rightItem) {
467471
continue;
468472
}
469473

470-
Py_INCREF(leftItem);
474+
Py_XINCREF(leftItem);
471475
Py_INCREF(rightItem);
472476
int k = PyObject_RichCompareBool(leftItem, rightItem, Py_EQ);
473-
Py_DECREF(leftItem);
477+
Py_XDECREF(leftItem);
474478
Py_DECREF(rightItem);
475479
if (k < 0) {
476480
return NULL;
477481
}
478482
if (!k) {
479483
break;
480484
}
485+
486+
Py_XDECREF(leftItem);
487+
if (needToDecRefRightItem) {
488+
Py_DECREF(rightItem);
489+
}
481490
}
482491

483492
if (index >= selfLength || index >= otherLength) {
@@ -497,7 +506,7 @@ PyObject *JSArrayProxyMethodDefinitions::JSArrayProxy_richcompare(JSArrayProxy *
497506
/* Compare the final item again using the proper operator */
498507
PyObject *pyElementVal = pyTypeFactory(GLOBAL_CX, elementVal);
499508
PyObject *result = PyObject_RichCompare(pyElementVal, ((PyListObject *)other)->ob_item[index], op);
500-
Py_DECREF(pyElementVal);
509+
Py_XDECREF(pyElementVal);
501510
return result;
502511
}
503512

@@ -542,7 +551,7 @@ PyObject *JSArrayProxyMethodDefinitions::JSArrayProxy_repr(JSArrayProxy *self) {
542551
} else {
543552
PyObject *pyElementVal = pyTypeFactory(GLOBAL_CX, elementVal);
544553
s = PyObject_Repr(pyElementVal);
545-
Py_DECREF(pyElementVal);
554+
Py_XDECREF(pyElementVal);
546555
}
547556
if (s == NULL) {
548557
goto error;
@@ -687,9 +696,10 @@ int JSArrayProxyMethodDefinitions::JSArrayProxy_contains(JSArrayProxy *self, PyO
687696
for (index = 0, cmp = 0; cmp == 0 && index < numElements; ++index) {
688697
JS_GetElement(GLOBAL_CX, *(self->jsArray), index, &elementVal);
689698
PyObject *item = pyTypeFactory(GLOBAL_CX, elementVal);
690-
Py_INCREF(item);
699+
Py_XINCREF(item);
691700
cmp = PyObject_RichCompareBool(item, element, Py_EQ);
692-
Py_DECREF(item);
701+
Py_XDECREF(item);
702+
Py_XDECREF(item);
693703
}
694704
return cmp;
695705
}
@@ -948,9 +958,10 @@ PyObject *JSArrayProxyMethodDefinitions::JSArrayProxy_remove(JSArrayProxy *self,
948958
for (Py_ssize_t index = 0; index < selfSize; index++) {
949959
JS_GetElement(GLOBAL_CX, *(self->jsArray), index, &elementVal);
950960
PyObject *obj = pyTypeFactory(GLOBAL_CX, elementVal);
951-
Py_INCREF(obj);
961+
Py_XINCREF(obj);
952962
int cmp = PyObject_RichCompareBool(obj, value, Py_EQ);
953-
Py_DECREF(obj);
963+
Py_XDECREF(obj);
964+
Py_XDECREF(obj);
954965
if (cmp > 0) {
955966
JS::Rooted<JS::ValueArray<2>> jArgs(GLOBAL_CX);
956967
jArgs[0].setInt32(index);
@@ -1013,9 +1024,10 @@ PyObject *JSArrayProxyMethodDefinitions::JSArrayProxy_index(JSArrayProxy *self,
10131024
for (Py_ssize_t index = start; index < stop && index < selfSize; index++) {
10141025
JS_GetElement(GLOBAL_CX, *(self->jsArray), index, &elementVal);
10151026
PyObject *obj = pyTypeFactory(GLOBAL_CX, elementVal);
1016-
Py_INCREF(obj);
1027+
Py_XINCREF(obj);
10171028
int cmp = PyObject_RichCompareBool(obj, value, Py_EQ);
1018-
Py_DECREF(obj);
1029+
Py_XDECREF(obj);
1030+
Py_XDECREF(obj);
10191031
if (cmp > 0) {
10201032
return PyLong_FromSsize_t(index);
10211033
}
@@ -1036,9 +1048,10 @@ PyObject *JSArrayProxyMethodDefinitions::JSArrayProxy_count(JSArrayProxy *self,
10361048
for (Py_ssize_t index = 0; index < length; index++) {
10371049
JS_GetElement(GLOBAL_CX, *(self->jsArray), index, &elementVal);
10381050
PyObject *obj = pyTypeFactory(GLOBAL_CX, elementVal);
1039-
Py_INCREF(obj);
1051+
Py_XINCREF(obj);
10401052
int cmp = PyObject_RichCompareBool(obj, value, Py_EQ);
1041-
Py_DECREF(obj);
1053+
Py_XDECREF(obj);
1054+
Py_XDECREF(obj);
10421055
if (cmp > 0) {
10431056
count++;
10441057
}
@@ -1084,15 +1097,15 @@ static bool sort_compare_key_func(JSContext *cx, unsigned argc, JS::Value *vp) {
10841097
JS::RootedValue elementVal0(cx, args[0]);
10851098
PyObject *args_0 = pyTypeFactory(cx, elementVal0);
10861099
PyObject *args_0_result = PyObject_CallFunction(keyfunc, "O", args_0);
1087-
Py_DECREF(args_0);
1100+
Py_XDECREF(args_0);
10881101
if (!args_0_result) {
10891102
return false;
10901103
}
10911104

10921105
JS::RootedValue elementVal1(cx, args[1]);
10931106
PyObject *args_1 = pyTypeFactory(cx, elementVal1);
10941107
PyObject *args_1_result = PyObject_CallFunction(keyfunc, "O", args_1);
1095-
Py_DECREF(args_1);
1108+
Py_XDECREF(args_1);
10961109
if (!args_1_result) {
10971110
return false;
10981111
}
@@ -1150,13 +1163,19 @@ static bool sort_compare_default(JSContext *cx, unsigned argc, JS::Value *vp) {
11501163
args.rval().setInt32(reverse ? -1 : 1);
11511164
}
11521165
else {
1166+
Py_XDECREF(args_0);
1167+
Py_XDECREF(args_1);
11531168
return false;
11541169
}
11551170
}
11561171
else {
1172+
Py_XDECREF(args_0);
1173+
Py_XDECREF(args_1);
11571174
return false;
11581175
}
11591176

1177+
Py_XDECREF(args_0);
1178+
Py_XDECREF(args_1);
11601179
return true;
11611180
}
11621181

src/JSObjectIterProxy.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ PyObject *JSObjectIterProxyMethodDefinitions::JSObjectIterProxy_nextkey(JSObject
7878
ret = key;
7979
}
8080

81+
if (self->it.kind != KIND_KEYS) {
82+
Py_XDECREF(value);
83+
}
84+
8185
Py_INCREF(ret);
8286
return ret;
8387
}
@@ -103,6 +107,11 @@ PyObject *JSObjectIterProxyMethodDefinitions::JSObjectIterProxy_nextkey(JSObject
103107
else {
104108
ret = key;
105109
}
110+
111+
if (self->it.kind != KIND_KEYS) {
112+
Py_XDECREF(value);
113+
}
114+
106115
Py_INCREF(ret);
107116
return ret;
108117
}

src/JobQueue.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ bool JobQueue::enqueuePromiseJob(JSContext *cx,
4747

4848
loop.enqueue(callback);
4949

50+
Py_XDECREF(callback);
5051
return true;
5152
}
5253

src/PromiseType.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ static bool onResolvedCb(JSContext *cx, unsigned argc, JS::Value *vp) {
5858
future.setException(result);
5959
}
6060

61+
Py_XDECREF(result);
6162
return true;
6263
}
6364

src/PyListProxyHandler.cc

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ static bool makeNewPyMethod(JSContext *cx, JS::MutableHandleValue function, JS::
4747
thisValue.setObject(*thisObject);
4848
PyObject *newSelf = pyTypeFactory(cx, thisValue);
4949
function.set(jsTypeFactory(cx, PyMethod_New(func, newSelf)));
50-
Py_DECREF(newSelf);
50+
Py_XDECREF(newSelf);
5151

5252
return true;
5353
}
@@ -114,10 +114,10 @@ static bool array_push(JSContext *cx, unsigned argc, JS::Value *vp) { // surely
114114
elementVal.set(args[index].get());
115115
PyObject *value = pyTypeFactory(cx, elementVal);
116116
if (PyList_Append(self, value) < 0) {
117-
Py_DECREF(value);
117+
Py_XDECREF(value);
118118
return false;
119119
}
120-
Py_DECREF(value);
120+
Py_XDECREF(value);
121121
}
122122

123123
args.rval().setInt32(PyList_GET_SIZE(self));
@@ -166,10 +166,10 @@ static bool array_unshift(JSContext *cx, unsigned argc, JS::Value *vp) { // sure
166166
elementVal.set(args[index].get());
167167
PyObject *value = pyTypeFactory(cx, elementVal);
168168
if (PyList_Insert(self, 0, value) < 0) {
169-
Py_DECREF(value);
169+
Py_XDECREF(value);
170170
return false;
171171
}
172-
Py_DECREF(value);
172+
Py_XDECREF(value);
173173
}
174174

175175
args.rval().setInt32(PyList_GET_SIZE(self));
@@ -281,7 +281,7 @@ static bool array_indexOf(JSContext *cx, unsigned argc, JS::Value *vp) {
281281
JS::RootedValue elementVal(cx, args[0].get());
282282
PyObject *value = pyTypeFactory(cx, elementVal);
283283
PyObject *result = PyObject_CallMethod(self, "index", "Oi", value, start);
284-
Py_DECREF(value);
284+
Py_XDECREF(value);
285285

286286
if (!result) {
287287
PyErr_Clear();
@@ -364,10 +364,8 @@ static bool array_splice(JSContext *cx, unsigned argc, JS::Value *vp) {
364364
elementVal.set(args[index + 2].get());
365365
PyObject *value = pyTypeFactory(cx, elementVal);
366366
if (PyList_SetItem(inserted, index, value) < 0) {
367-
Py_DECREF(value);
368367
return false;
369368
}
370-
Py_DECREF(value);
371369
}
372370

373371
if (PyList_SetSlice(self, actualStart, actualStart + actualDeleteCount, inserted) < 0) {
@@ -430,12 +428,18 @@ static bool array_fill(JSContext *cx, unsigned argc, JS::Value *vp) {
430428

431429
JS::RootedValue fillValue(cx, args[0].get());
432430
PyObject *fillValueItem = pyTypeFactory(cx, fillValue);
431+
bool setItemCalled = false;
433432
for (int index = actualStart; index < actualEnd; index++) {
433+
setItemCalled = true;
434434
if (PyList_SetItem(self, index, fillValueItem) < 0) {
435435
return false;
436436
}
437437
}
438438

439+
if (!setItemCalled) {
440+
Py_XDECREF(fillValueItem);
441+
}
442+
439443
// return ref to self
440444
args.rval().set(jsTypeFactory(cx, self));
441445
return true;
@@ -564,27 +568,39 @@ static bool array_concat(JSContext *cx, unsigned argc, JS::Value *vp) {
564568
Py_ssize_t itemLength = JSArrayProxyMethodDefinitions::JSArrayProxy_length((JSArrayProxy *)item);
565569
for (Py_ssize_t flatIndex = 0; flatIndex < itemLength; flatIndex++) {
566570
if (!JS_GetElement(cx, *(((JSArrayProxy *)item)->jsArray), flatIndex, &elementVal)) {
571+
Py_XDECREF(item);
567572
return false;
568573
}
569-
if (PyList_Append(result, pyTypeFactory(cx, elementVal)) < 0) {
574+
PyObject *value = pyTypeFactory(cx, elementVal);
575+
if (PyList_Append(result, value) < 0) {
576+
Py_XDECREF(item);
577+
Py_XDECREF(value);
570578
return false;
571579
}
580+
Py_XDECREF(value);
572581
}
573582
}
574583
else if (PyObject_TypeCheck(item, &PyList_Type)) {
575584
// flatten the array only at depth 1
576585
Py_ssize_t itemLength = PyList_GET_SIZE(item);
577586
for (Py_ssize_t flatIndex = 0; flatIndex < itemLength; flatIndex++) {
578587
if (PyList_Append(result, PyList_GetItem(item, flatIndex)) < 0) {
588+
Py_XDECREF(item);
579589
return false;
580590
}
581591
}
582592
}
583593
else {
584-
if (PyList_Append(result, pyTypeFactory(cx, elementVal)) < 0) {
594+
PyObject *value = pyTypeFactory(cx, elementVal);
595+
if (PyList_Append(result, value) < 0) {
596+
Py_XDECREF(item);
597+
Py_XDECREF(value);
585598
return false;
586599
}
600+
Py_XDECREF(value);
587601
}
602+
603+
Py_XDECREF(item);
588604
}
589605

590606
args.rval().set(jsTypeFactory(cx, result));
@@ -639,13 +655,16 @@ static bool array_lastIndexOf(JSContext *cx, unsigned argc, JS::Value *vp) {
639655
int cmp = PyObject_RichCompareBool(item, element, Py_EQ);
640656
Py_DECREF(item);
641657
if (cmp < 0) {
658+
Py_XDECREF(element);
642659
return false;
643660
}
644661
else if (cmp == 1) {
662+
Py_XDECREF(element);
645663
args.rval().setInt32(index);
646664
return true;
647665
}
648666
}
667+
Py_XDECREF(element);
649668

650669
args.rval().setInt32(-1);
651670
return true;
@@ -1247,7 +1266,6 @@ static uint32_t FlattenIntoArray(JSContext *cx,
12471266
JS::RootedValue elementVal(cx);
12481267

12491268
for (uint32_t sourceIndex = 0; sourceIndex < sourceLen; sourceIndex++) {
1250-
12511269
if (PyObject_TypeCheck(source, &JSArrayProxyType)) {
12521270
JS_GetElement(cx, *(((JSArrayProxy *)source)->jsArray), sourceIndex, &elementVal);
12531271
}
@@ -1294,6 +1312,8 @@ static uint32_t FlattenIntoArray(JSContext *cx,
12941312

12951313
targetIndex++;
12961314
}
1315+
1316+
Py_XDECREF(element);
12971317
}
12981318

12991319
return targetIndex;
@@ -1391,6 +1411,8 @@ static uint32_t FlattenIntoArrayWithCallBack(JSContext *cx,
13911411
targetIndex++;
13921412
}
13931413
}
1414+
1415+
Py_XDECREF(element);
13941416
}
13951417

13961418
return targetIndex;

src/PyObjectProxyHandler.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,10 @@ bool PyObjectProxyHandler::set(JSContext *cx, JS::HandleObject proxy, JS::Handle
176176
PyObject *self = JS::GetMaybePtrFromReservedSlot<PyObject>(proxy, PyObjectSlot);
177177
PyObject *value = pyTypeFactory(cx, rootedV);
178178
if (PyObject_SetAttr(self, attrName, value)) {
179-
Py_DECREF(value);
179+
Py_XDECREF(value);
180180
return result.failCantSetInterposed(); // raises JS exception
181181
}
182-
Py_DECREF(value);
182+
Py_XDECREF(value);
183183
return result.succeed();
184184
}
185185

src/internalBinding/timers.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ static bool enqueueWithDelay(JSContext *cx, unsigned argc, JS::Value *vp) {
3232
PyEventLoop loop = PyEventLoop::getRunningLoop();
3333
if (!loop.initialized()) return false;
3434
PyEventLoop::AsyncHandle::id_t handleId = loop.enqueueWithDelay(job, delaySeconds, repeat);
35-
Py_DECREF(job);
35+
Py_XDECREF(job);
3636

3737
// Return the `timeoutID` to use in `clearTimeout`
3838
args.rval().setNumber(handleId);

0 commit comments

Comments
 (0)