@@ -164,56 +164,91 @@ PLyObject_FromJsonbContainer(JsonbContainer *jsonb)
164
164
}
165
165
else
166
166
{
167
- /* array in v */
167
+ PyObject * volatile elem = NULL ;
168
+
168
169
result = PyList_New (0 );
169
170
if (!result )
170
171
return NULL ;
171
172
172
- while (( r = JsonbIteratorNext ( & it , & v , true)) != WJB_DONE )
173
+ PG_TRY ();
173
174
{
174
- if ( r == WJB_ELEM )
175
+ while (( r = JsonbIteratorNext ( & it , & v , true)) != WJB_DONE )
175
176
{
176
- PyObject * elem = PLyObject_FromJsonbValue (& v );
177
+ if (r != WJB_ELEM )
178
+ continue ;
179
+
180
+ elem = PLyObject_FromJsonbValue (& v );
177
181
178
182
PyList_Append (result , elem );
179
183
Py_XDECREF (elem );
184
+ elem = NULL ;
180
185
}
181
186
}
187
+ PG_CATCH ();
188
+ {
189
+ Py_XDECREF (elem );
190
+ Py_XDECREF (result );
191
+ PG_RE_THROW ();
192
+ }
193
+ PG_END_TRY ();
182
194
}
183
195
break ;
184
196
185
197
case WJB_BEGIN_OBJECT :
186
- result = PyDict_New ();
187
- if (!result )
188
- return NULL ;
189
-
190
- while ((r = JsonbIteratorNext (& it , & v , true)) != WJB_DONE )
191
198
{
192
- if ( r == WJB_KEY )
193
- {
194
- PyObject * key = PLyString_FromJsonbValue ( & v ) ;
199
+ PyObject * volatile result_v = PyDict_New ();
200
+ PyObject * volatile key = NULL ;
201
+ PyObject * volatile val = NULL ;
195
202
196
- if (!key )
197
- return NULL ;
198
-
199
- r = JsonbIteratorNext (& it , & v , true);
203
+ if (!result_v )
204
+ return NULL ;
200
205
201
- if (r == WJB_VALUE )
206
+ PG_TRY ();
207
+ {
208
+ while ((r = JsonbIteratorNext (& it , & v , true)) != WJB_DONE )
202
209
{
203
- PyObject * value = PLyObject_FromJsonbValue (& v );
210
+ if (r != WJB_KEY )
211
+ continue ;
204
212
205
- if (!value )
213
+ key = PLyString_FromJsonbValue (& v );
214
+ if (!key )
215
+ {
216
+ Py_XDECREF (result_v );
217
+ result_v = NULL ;
218
+ break ;
219
+ }
220
+
221
+ if ((r = JsonbIteratorNext (& it , & v , true)) != WJB_VALUE )
222
+ elog (ERROR , "unexpected jsonb token: %d" , r );
223
+
224
+ val = PLyObject_FromJsonbValue (& v );
225
+ if (!val )
206
226
{
207
227
Py_XDECREF (key );
208
- return NULL ;
228
+ key = NULL ;
229
+ Py_XDECREF (result_v );
230
+ result_v = NULL ;
231
+ break ;
209
232
}
210
233
211
- PyDict_SetItem (result , key , value );
212
- Py_XDECREF (value );
213
- }
234
+ PyDict_SetItem (result_v , key , val );
214
235
236
+ Py_XDECREF (key );
237
+ key = NULL ;
238
+ Py_XDECREF (val );
239
+ val = NULL ;
240
+ }
241
+ }
242
+ PG_CATCH ();
243
+ {
244
+ Py_XDECREF (result_v );
215
245
Py_XDECREF (key );
246
+ Py_XDECREF (val );
247
+ PG_RE_THROW ();
216
248
}
249
+ PG_END_TRY ();
250
+
251
+ result = result_v ;
217
252
}
218
253
break ;
219
254
@@ -234,10 +269,8 @@ static JsonbValue *
234
269
PLyMapping_ToJsonbValue (PyObject * obj , JsonbParseState * * jsonb_state )
235
270
{
236
271
Py_ssize_t pcount ;
237
- JsonbValue * out = NULL ;
238
-
239
- /* We need it volatile, since we use it after longjmp */
240
- PyObject * volatile items = NULL ;
272
+ PyObject * volatile items ;
273
+ JsonbValue * volatile out ;
241
274
242
275
pcount = PyMapping_Size (obj );
243
276
items = PyMapping_Items (obj );
@@ -281,6 +314,8 @@ PLyMapping_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state)
281
314
}
282
315
PG_END_TRY ();
283
316
317
+ Py_DECREF (items );
318
+
284
319
return out ;
285
320
}
286
321
@@ -295,19 +330,30 @@ PLySequence_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state)
295
330
{
296
331
Py_ssize_t i ;
297
332
Py_ssize_t pcount ;
333
+ PyObject * volatile value = NULL ;
298
334
299
335
pcount = PySequence_Size (obj );
300
336
301
337
pushJsonbValue (jsonb_state , WJB_BEGIN_ARRAY , NULL );
302
338
303
- for ( i = 0 ; i < pcount ; i ++ )
339
+ PG_TRY ();
304
340
{
305
- PyObject * value = PySequence_GetItem (obj , i );
306
-
307
- (void ) PLyObject_ToJsonbValue (value , jsonb_state , true);
341
+ for (i = 0 ; i < pcount ; i ++ )
342
+ {
343
+ value = PySequence_GetItem (obj , i );
344
+ Assert (value );
308
345
346
+ (void ) PLyObject_ToJsonbValue (value , jsonb_state , true);
347
+ Py_XDECREF (value );
348
+ value = NULL ;
349
+ }
350
+ }
351
+ PG_CATCH ();
352
+ {
309
353
Py_XDECREF (value );
354
+ PG_RE_THROW ();
310
355
}
356
+ PG_END_TRY ();
311
357
312
358
return pushJsonbValue (jsonb_state , WJB_END_ARRAY , NULL );
313
359
}
0 commit comments