@@ -169,53 +169,80 @@ PLyObject_FromJsonbContainer(JsonbContainer *jsonb)
169
169
if (!result )
170
170
return NULL ;
171
171
172
- while (( r = JsonbIteratorNext ( & it , & v , true)) != WJB_DONE )
172
+ PG_TRY ();
173
173
{
174
- if ( r == WJB_ELEM )
174
+ while (( r = JsonbIteratorNext ( & it , & v , true)) != WJB_DONE )
175
175
{
176
- PyObject * elem = PLyObject_FromJsonbValue (& v );
176
+ if (r == WJB_ELEM )
177
+ {
178
+ PyObject * elem = PLyObject_FromJsonbValue (& v );
179
+
180
+ if (!elem || PyList_Append (result ,elem ))
181
+ {
182
+ Py_XDECREF (elem );
183
+ Py_DECREF (result );
184
+ return NULL ;
185
+ }
177
186
178
- PyList_Append ( result , elem );
179
- Py_XDECREF ( elem );
187
+ Py_DECREF ( elem );
188
+ }
180
189
}
181
190
}
191
+ PG_CATCH ();
192
+ {
193
+ Py_DECREF (result );
194
+ PG_RE_THROW ();
195
+ }
196
+ PG_END_TRY ();
182
197
}
183
198
break ;
184
199
185
200
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
201
{
192
- if (r == WJB_KEY )
193
- {
194
- PyObject * key = PLyString_FromJsonbValue (& v );
195
-
196
- if (!key )
197
- return NULL ;
202
+ PyObject * volatile key = NULL ;
198
203
199
- r = JsonbIteratorNext (& it ,& v , true);
204
+ result = PyDict_New ();
205
+ if (!result )
206
+ return NULL ;
200
207
201
- if (r == WJB_VALUE )
208
+ PG_TRY ();
209
+ {
210
+ while ((r = JsonbIteratorNext (& it ,& v , true))!= WJB_DONE )
202
211
{
203
- PyObject * value = PLyObject_FromJsonbValue (& v );
212
+ JsonbValue v2 ;
213
+ PyObject * val = NULL ;
214
+
215
+ if (r != WJB_KEY )
216
+ continue ;
217
+
218
+ if ((r = JsonbIteratorNext (& it ,& v2 , true))!= WJB_VALUE )
219
+ elog (ERROR ,"unexpected jsonb token: %d" ,r );
204
220
205
- if (!value )
221
+ if (!(key = PLyString_FromJsonbValue (& v ))||
222
+ !(val = PLyObject_FromJsonbValue (& v2 ))||
223
+ PyDict_SetItem (result ,key ,val ))
206
224
{
207
225
Py_XDECREF (key );
226
+ Py_XDECREF (val );
227
+ Py_DECREF (result );
208
228
return NULL ;
209
229
}
210
230
211
- PyDict_SetItem (result ,key ,value );
212
- Py_XDECREF (value );
231
+ Py_DECREF (val );
232
+ Py_DECREF (key );
233
+ key = NULL ;
213
234
}
214
-
235
+ }
236
+ PG_CATCH ();
237
+ {
215
238
Py_XDECREF (key );
239
+ Py_DECREF (result );
240
+ PG_RE_THROW ();
216
241
}
242
+ PG_END_TRY ();
243
+
244
+ break ;
217
245
}
218
- break ;
219
246
220
247
default :
221
248
elog (ERROR ,"unexpected jsonb token: %d" ,r );
@@ -233,30 +260,40 @@ PLyObject_FromJsonbContainer(JsonbContainer *jsonb)
233
260
static JsonbValue *
234
261
PLyMapping_ToJsonbValue (PyObject * obj ,JsonbParseState * * jsonb_state )
235
262
{
236
- Py_ssize_t pcount ;
237
- JsonbValue * out = NULL ;
263
+ JsonbValue * out ;
264
+ PyObject * items ;
265
+ Py_ssize_t pcount = PyMapping_Size (obj );
266
+
267
+ if (pcount < 0 )
268
+ PLy_elog (ERROR ,"PyMapping_Size() failed, while converting mapping into jsonb" );
238
269
239
- /* We need it volatile, since we use it after longjmp */
240
- volatile PyObject * items_v = NULL ;
270
+ items = PyMapping_Items (obj );
241
271
242
- pcount = PyMapping_Size ( obj );
243
- items_v = PyMapping_Items (obj );
272
+ if (! items )
273
+ PLy_elog ( ERROR , " PyMapping_Items() failed, while converting mapping into jsonb" );
244
274
245
275
PG_TRY ();
246
276
{
247
277
Py_ssize_t i ;
248
- PyObject * items ;
249
-
250
- items = (PyObject * )items_v ;
251
278
252
279
pushJsonbValue (jsonb_state ,WJB_BEGIN_OBJECT ,NULL );
253
280
254
281
for (i = 0 ;i < pcount ;i ++ )
255
282
{
256
283
JsonbValue jbvKey ;
257
- PyObject * item = PyList_GetItem (items ,i );
258
- PyObject * key = PyTuple_GetItem (item ,0 );
259
- PyObject * value = PyTuple_GetItem (item ,1 );
284
+ PyObject * item ;
285
+ PyObject * key ;
286
+ PyObject * value ;
287
+
288
+ item = PyList_GetItem (items ,i );/* borrowed reference */
289
+ if (!item )
290
+ PLy_elog (ERROR ,"PyList_GetItem() failed, while converting mapping into jsonb" );
291
+
292
+ key = PyTuple_GetItem (item ,0 );/* borrowed references */
293
+ value = PyTuple_GetItem (item ,1 );
294
+
295
+ if (!key || !value )
296
+ PLy_elog (ERROR ,"PyTuple_GetItem() failed, while converting mapping into jsonb" );
260
297
261
298
/* Python dictionary can have None as key */
262
299
if (key == Py_None )
@@ -279,11 +316,13 @@ PLyMapping_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state)
279
316
}
280
317
PG_CATCH ();
281
318
{
282
- Py_DECREF (items_v );
319
+ Py_DECREF (items );
283
320
PG_RE_THROW ();
284
321
}
285
322
PG_END_TRY ();
286
323
324
+ Py_DECREF (items );
325
+
287
326
return out ;
288
327
}
289
328
@@ -296,21 +335,36 @@ PLyMapping_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state)
296
335
static JsonbValue *
297
336
PLySequence_ToJsonbValue (PyObject * obj ,JsonbParseState * * jsonb_state )
298
337
{
299
- Py_ssize_t i ;
300
- Py_ssize_t pcount ;
338
+ PyObject * seq = PySequence_Fast (obj ,"object is not a sequence" );
301
339
302
- pcount = PySequence_Size (obj );
340
+ if (!seq )
341
+ PLy_elog (ERROR ,"PySequence_Fast() failed, while converting sequence into jsonb" );
303
342
304
- pushJsonbValue (jsonb_state ,WJB_BEGIN_ARRAY ,NULL );
305
-
306
- for (i = 0 ;i < pcount ;i ++ )
343
+ PG_TRY ();
307
344
{
308
- PyObject * value = PySequence_GetItem (obj ,i );
345
+ Py_ssize_t i ;
346
+ Py_ssize_t pcount = PySequence_Fast_GET_SIZE (seq );
309
347
310
- ( void ) PLyObject_ToJsonbValue ( value , jsonb_state , true );
348
+ pushJsonbValue ( jsonb_state , WJB_BEGIN_ARRAY , NULL );
311
349
312
- Py_XDECREF (value );
350
+ for (i = 0 ;i < pcount ;i ++ )
351
+ {
352
+ PyObject * value = PySequence_Fast_GET_ITEM (seq ,i );/* borrowed reference */
353
+
354
+ if (!value )
355
+ PLy_elog (ERROR ,"PySequence_Fast_GET_ITEM() failed, while converting sequence into jsonb" );
356
+
357
+ (void )PLyObject_ToJsonbValue (value ,jsonb_state , true);
358
+ }
313
359
}
360
+ PG_CATCH ();
361
+ {
362
+ Py_DECREF (seq );
363
+ PG_RE_THROW ();
364
+ }
365
+ PG_END_TRY ();
366
+
367
+ Py_DECREF (seq );
314
368
315
369
return pushJsonbValue (jsonb_state ,WJB_END_ARRAY ,NULL );
316
370
}