File: | libcpychecker/html/test/example2/pylibmc-issue-68.c |
Function: | PylibMC_Client_get_multi |
Error: | ob_refcnt of '*rkey.14' is 1 too high |
52 /* Extracted copy of PylibMC_Client_get_multi */
53 static PyObject *PylibMC_Client_get_multi(
54 PylibMC_Client *self, PyObject *args, PyObject *kwds) {
55 PyObject *key_seq, **key_objs, *retval = NULL;
56 char **keys, *prefix = NULL;
57 char *err_func = NULL;
58 memcached_result_st *res, *results = NULL;
59 int prefix_len = 0;
60 Py_ssize_t i;
61 PyObject *key_it, *ckey;
62 size_t *key_lens;
63 size_t nkeys, nresults = 0;
64 memcached_return rc;
65
66 static char *kws[] = { "keys", "key_prefix", NULL };
67
68 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s#:get_multi", kws,
when _PyArg_ParseTupleAndKeywords_SizeT() succeeds
taking False path
69 &key_seq, &prefix, &prefix_len))
70 return NULL;
71
72 if ((nkeys = (size_t)PySequence_Length(key_seq)) == -1)
when PySequence_Size() succeeds
taking False path
73 return NULL;
74
75 /* Populate keys and key_lens. */
76 keys = PyMem_New(char *, nkeys);
when considering range: 0 <= value <= 0xfffffffffffffff
taking True path
when PyMem_Malloc() succeeds
77 key_lens = PyMem_New(size_t, nkeys);
taking True path
when PyMem_Malloc() succeeds
78 key_objs = PyMem_New(PyObject *, nkeys);
taking True path
when PyMem_Malloc() succeeds
79 if (!keys || !key_lens || !key_objs) {
taking False path
taking False path
taking False path
80 PyMem_Free(keys);
81 PyMem_Free(key_lens);
82 PyMem_Free(key_objs);
83 return PyErr_NoMemory();
84 }
85
86 /* Clear potential previous exception, because we explicitly check for
87 * exceptions as a loop predicate. */
88 PyErr_Clear();
calling PyErr_Clear()
89
90 /* Iterate through all keys and set lengths etc. */
91 key_it = PyObject_GetIter(key_seq);
when PyObject_GetIter() succeeds
92 i = 0;
93 while ((ckey = PyIter_Next(key_it)) != NULL) {
when PyIter_Next() retrieves a value (new ref)
taking True path
when PyIter_Next() returns NULL without setting an exception (end of iteration)
taking False path
94 char *key;
95 Py_ssize_t key_len;
96 PyObject *rkey;
97
98 assert(i < nkeys);
when considering range: 1 <= nkeys <= 0xfffffffffffffff
taking False path
99
100 if (PyErr_Occurred() || !_PylibMC_CheckKey(ckey)) {
PyErr_Occurred()
taking False path
when considering range: -0x80000000 <= value <= -1
taking False path
101 nkeys = i;
102 goto earlybird;
103 }
104
105 PyString_AsStringAndSize(ckey, &key, &key_len);
106
107 key_lens[i] = (size_t)(key_len + prefix_len);
108
109 /* Skip empty keys */
110 if (!key_lens[i])
when considering range: -0x8000000000000000 <= value <= -1
taking False path
111 continue;
112
113 /* determine rkey, the prefixed ckey */
114 if (prefix != NULL) {
when treating unknown const char * from libcpychecker/html/test/example2/pylibmc-issue-68.c:68 as non-NULL
taking True path
115 rkey = PyString_FromStringAndSize(prefix, prefix_len);
when PyString_FromStringAndSize() succeeds
116 PyString_Concat(&rkey, ckey);
result of PyString_Concat allocated at: PyString_Concat(&rkey, ckey);
117 if (rkey == NULL)
when PyString_Concat() succeeds (Py_DECREF() without deallocation on *LHS)
taking False path
118 goto earlybird;
119 rkey = PyString_FromFormat("%s%s",
when PyString_FromFormat() succeeds
120 prefix, PyString_AS_STRING(ckey));
121 } else {
122 Py_INCREF(ckey);
123 rkey = ckey;
124 }
125 Py_DECREF(ckey);
when taking True path
126
127 keys[i] = PyString_AS_STRING(rkey);
128 key_objs[i++] = rkey;
129 }
130 nkeys = i;
131 Py_XDECREF(key_it);
taking False path
when taking True path
132
133 if (nkeys == 0) {
taking False path
134 retval = PyDict_New();
135 goto earlybird;
136 } else if (PyErr_Occurred()) {
PyErr_Occurred()
taking False path
137 nkeys--;
138 goto earlybird;
139 }
140
141 /* TODO Make an iterator interface for getting each key separately.
142 *
143 * This would help large retrievals, as a single dictionary containing all
144 * the data at once isn't needed. (Should probably look into if it's even
145 * worth it.)
146 */
147 Py_BEGIN_ALLOW_THREADS;
releasing the GIL by calling PyEval_SaveThread()
148 rc = pylibmc_memcached_fetch_multi(self->mc,
149 keys, nkeys, key_lens,
150 &results, &nresults,
151 &err_func);
152 Py_END_ALLOW_THREADS;
reacquiring the GIL by calling PyEval_RestoreThread()
153
154 if (rc != MEMCACHED_SUCCESS) {
when considering value == (int)0 from libcpychecker/html/test/example2/pylibmc-issue-68.c:148
taking False path
155 PylibMC_ErrFromMemcached(self, err_func, rc);
156 goto earlybird;
157 }
158
159 retval = PyDict_New();
when PyDict_New() succeeds
160
161 for (i = 0; i < nresults; i++) {
when taking True path
162 PyObject *val, *key_obj;
163 int rc;
164
165 res = results + i;
166
167 /* Explicitly construct a key string object so that NUL-bytes and the
168 * likes can be contained within the keys (this is possible in the
169 * binary protocol.) */
170 key_obj = PyString_FromStringAndSize(memcached_result_key_value(res) + prefix_len,
when PyString_FromStringAndSize() succeeds
171 memcached_result_key_length(res) - prefix_len);
172 if (key_obj == NULL)
taking False path
173 goto unpack_error;
174
175 /* Parse out value */
176 val = _PylibMC_parse_memcached_result(res);
177 if (val == NULL)
when treating unknown struct PyObject * from libcpychecker/html/test/example2/pylibmc-issue-68.c:176 as non-NULL
taking False path
178 goto unpack_error;
179
180 rc = PyDict_SetItem(retval, key_obj, val);
when PyDict_SetItem() fails
181 Py_DECREF(key_obj);
when taking True path
182 Py_DECREF(val);
when considering range: -0x8000000000000000 <= value <= -1
taking True path
183
184 if (rc != 0)
taking True path
185 goto unpack_error;
186
187 continue;
188
189 unpack_error:
190 Py_DECREF(retval);
when taking True path
191 break;
192 }
193
194 earlybird:
195 PyMem_Free(key_lens);
calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:77
196 PyMem_Free(keys);
calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:76
197
198 for (i = 0; i < nkeys; i++)
taking True path
taking False path
199 Py_DECREF(key_objs[i]);
when taking True path
200 PyMem_Free(key_objs);
calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:78
201
202 if (results != NULL) {
when treating unknown struct memcached_result_st * * from libcpychecker/html/test/example2/pylibmc-issue-68.c:148 as non-NULL
taking True path
203 for (i = 0; i < nresults && results != NULL; i++) {
when taking True path
taking True path
when taking False path
204 memcached_result_free(results + i);
205 }
206 PyMem_Free(results);
calling PyMem_Free on Region('heap-region-10')
207 }
208
209 /* Not INCREFing because the only two outcomes are NULL and a new dict.
210 * We're the owner of that dict already, so. */
211 return retval;
212 }
ob_refcnt of '*rkey.14' is 1 too high
was expecting final ob_refcnt to be N + 0 (for some unknown N)
but final ob_refcnt is N + 1
found 47 similar trace(s) to this
File: | libcpychecker/html/test/example2/pylibmc-issue-68.c |
Function: | PylibMC_Client_get_multi |
Error: | ob_refcnt of return value is 1 too low |
52 /* Extracted copy of PylibMC_Client_get_multi */
53 static PyObject *PylibMC_Client_get_multi(
54 PylibMC_Client *self, PyObject *args, PyObject *kwds) {
55 PyObject *key_seq, **key_objs, *retval = NULL;
56 char **keys, *prefix = NULL;
57 char *err_func = NULL;
58 memcached_result_st *res, *results = NULL;
59 int prefix_len = 0;
60 Py_ssize_t i;
61 PyObject *key_it, *ckey;
62 size_t *key_lens;
63 size_t nkeys, nresults = 0;
64 memcached_return rc;
65
66 static char *kws[] = { "keys", "key_prefix", NULL };
67
68 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s#:get_multi", kws,
when _PyArg_ParseTupleAndKeywords_SizeT() succeeds
taking False path
69 &key_seq, &prefix, &prefix_len))
70 return NULL;
71
72 if ((nkeys = (size_t)PySequence_Length(key_seq)) == -1)
when PySequence_Size() succeeds
taking False path
73 return NULL;
74
75 /* Populate keys and key_lens. */
76 keys = PyMem_New(char *, nkeys);
when considering range: 0 <= value <= 0xfffffffffffffff
taking True path
when PyMem_Malloc() succeeds
77 key_lens = PyMem_New(size_t, nkeys);
taking True path
when PyMem_Malloc() succeeds
78 key_objs = PyMem_New(PyObject *, nkeys);
taking True path
when PyMem_Malloc() succeeds
79 if (!keys || !key_lens || !key_objs) {
taking False path
taking False path
taking False path
80 PyMem_Free(keys);
81 PyMem_Free(key_lens);
82 PyMem_Free(key_objs);
83 return PyErr_NoMemory();
84 }
85
86 /* Clear potential previous exception, because we explicitly check for
87 * exceptions as a loop predicate. */
88 PyErr_Clear();
calling PyErr_Clear()
89
90 /* Iterate through all keys and set lengths etc. */
91 key_it = PyObject_GetIter(key_seq);
when PyObject_GetIter() succeeds
92 i = 0;
93 while ((ckey = PyIter_Next(key_it)) != NULL) {
when PyIter_Next() retrieves a value (new ref)
taking True path
when PyIter_Next() returns NULL without setting an exception (end of iteration)
taking False path
94 char *key;
95 Py_ssize_t key_len;
96 PyObject *rkey;
97
98 assert(i < nkeys);
when considering range: 1 <= nkeys <= 0xfffffffffffffff
taking False path
99
100 if (PyErr_Occurred() || !_PylibMC_CheckKey(ckey)) {
PyErr_Occurred()
taking False path
when considering range: -0x80000000 <= value <= -1
taking False path
101 nkeys = i;
102 goto earlybird;
103 }
104
105 PyString_AsStringAndSize(ckey, &key, &key_len);
106
107 key_lens[i] = (size_t)(key_len + prefix_len);
108
109 /* Skip empty keys */
110 if (!key_lens[i])
when considering range: -0x8000000000000000 <= value <= -1
taking False path
111 continue;
112
113 /* determine rkey, the prefixed ckey */
114 if (prefix != NULL) {
when treating unknown const char * from libcpychecker/html/test/example2/pylibmc-issue-68.c:68 as non-NULL
taking True path
115 rkey = PyString_FromStringAndSize(prefix, prefix_len);
when PyString_FromStringAndSize() succeeds
116 PyString_Concat(&rkey, ckey);
117 if (rkey == NULL)
when PyString_Concat() succeeds (Py_DECREF() without deallocation on *LHS)
taking False path
118 goto earlybird;
119 rkey = PyString_FromFormat("%s%s",
when PyString_FromFormat() succeeds
120 prefix, PyString_AS_STRING(ckey));
121 } else {
122 Py_INCREF(ckey);
123 rkey = ckey;
124 }
125 Py_DECREF(ckey);
when taking True path
126
127 keys[i] = PyString_AS_STRING(rkey);
128 key_objs[i++] = rkey;
129 }
130 nkeys = i;
131 Py_XDECREF(key_it);
taking False path
when taking True path
132
133 if (nkeys == 0) {
taking False path
134 retval = PyDict_New();
135 goto earlybird;
136 } else if (PyErr_Occurred()) {
PyErr_Occurred()
taking False path
137 nkeys--;
138 goto earlybird;
139 }
140
141 /* TODO Make an iterator interface for getting each key separately.
142 *
143 * This would help large retrievals, as a single dictionary containing all
144 * the data at once isn't needed. (Should probably look into if it's even
145 * worth it.)
146 */
147 Py_BEGIN_ALLOW_THREADS;
releasing the GIL by calling PyEval_SaveThread()
148 rc = pylibmc_memcached_fetch_multi(self->mc,
149 keys, nkeys, key_lens,
150 &results, &nresults,
151 &err_func);
152 Py_END_ALLOW_THREADS;
reacquiring the GIL by calling PyEval_RestoreThread()
153
154 if (rc != MEMCACHED_SUCCESS) {
when considering value == (int)0 from libcpychecker/html/test/example2/pylibmc-issue-68.c:148
taking False path
155 PylibMC_ErrFromMemcached(self, err_func, rc);
156 goto earlybird;
157 }
158
159 retval = PyDict_New();
when PyDict_New() succeeds
PyDictObject allocated at: retval = PyDict_New();
ob_refcnt is now refs: 1 + N where N >= 0
160
161 for (i = 0; i < nresults; i++) {
when taking True path
162 PyObject *val, *key_obj;
163 int rc;
164
165 res = results + i;
166
167 /* Explicitly construct a key string object so that NUL-bytes and the
168 * likes can be contained within the keys (this is possible in the
169 * binary protocol.) */
170 key_obj = PyString_FromStringAndSize(memcached_result_key_value(res) + prefix_len,
when PyString_FromStringAndSize() succeeds
171 memcached_result_key_length(res) - prefix_len);
172 if (key_obj == NULL)
taking False path
173 goto unpack_error;
174
175 /* Parse out value */
176 val = _PylibMC_parse_memcached_result(res);
177 if (val == NULL)
when treating unknown struct PyObject * from libcpychecker/html/test/example2/pylibmc-issue-68.c:176 as non-NULL
taking False path
178 goto unpack_error;
179
180 rc = PyDict_SetItem(retval, key_obj, val);
when PyDict_SetItem() fails
181 Py_DECREF(key_obj);
when taking True path
182 Py_DECREF(val);
when considering range: -0x8000000000000000 <= value <= -1
taking True path
183
184 if (rc != 0)
taking True path
185 goto unpack_error;
186
187 continue;
188
189 unpack_error:
190 Py_DECREF(retval);
when taking True path
ob_refcnt is now refs: 0 + N where N >= 0
191 break;
192 }
193
194 earlybird:
195 PyMem_Free(key_lens);
calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:77
196 PyMem_Free(keys);
calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:76
197
198 for (i = 0; i < nkeys; i++)
taking True path
taking False path
199 Py_DECREF(key_objs[i]);
when taking True path
200 PyMem_Free(key_objs);
calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:78
201
202 if (results != NULL) {
when treating unknown struct memcached_result_st * * from libcpychecker/html/test/example2/pylibmc-issue-68.c:148 as non-NULL
taking True path
203 for (i = 0; i < nresults && results != NULL; i++) {
when taking True path
taking True path
when taking False path
204 memcached_result_free(results + i);
205 }
206 PyMem_Free(results);
calling PyMem_Free on Region('heap-region-10')
207 }
208
209 /* Not INCREFing because the only two outcomes are NULL and a new dict.
210 * We're the owner of that dict already, so. */
211 return retval;
212 }
ob_refcnt of return value is 1 too low
was expecting final ob_refcnt to be N + 1 (for some unknown N)
due to object being referenced by: return value
but final ob_refcnt is N + 0
found 11 similar trace(s) to this
File: | libcpychecker/html/test/example2/pylibmc-issue-68.c |
Function: | PylibMC_Client_get_multi |
Error: | returning pointer to deallocated memory |
52 /* Extracted copy of PylibMC_Client_get_multi */
53 static PyObject *PylibMC_Client_get_multi(
54 PylibMC_Client *self, PyObject *args, PyObject *kwds) {
55 PyObject *key_seq, **key_objs, *retval = NULL;
56 char **keys, *prefix = NULL;
57 char *err_func = NULL;
58 memcached_result_st *res, *results = NULL;
59 int prefix_len = 0;
60 Py_ssize_t i;
61 PyObject *key_it, *ckey;
62 size_t *key_lens;
63 size_t nkeys, nresults = 0;
64 memcached_return rc;
65
66 static char *kws[] = { "keys", "key_prefix", NULL };
67
68 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s#:get_multi", kws,
when _PyArg_ParseTupleAndKeywords_SizeT() succeeds
taking False path
69 &key_seq, &prefix, &prefix_len))
70 return NULL;
71
72 if ((nkeys = (size_t)PySequence_Length(key_seq)) == -1)
when PySequence_Size() succeeds
taking False path
73 return NULL;
74
75 /* Populate keys and key_lens. */
76 keys = PyMem_New(char *, nkeys);
when considering range: 0 <= value <= 0xfffffffffffffff
taking True path
when PyMem_Malloc() succeeds
77 key_lens = PyMem_New(size_t, nkeys);
taking True path
when PyMem_Malloc() succeeds
78 key_objs = PyMem_New(PyObject *, nkeys);
taking True path
when PyMem_Malloc() succeeds
79 if (!keys || !key_lens || !key_objs) {
taking False path
taking False path
taking False path
80 PyMem_Free(keys);
81 PyMem_Free(key_lens);
82 PyMem_Free(key_objs);
83 return PyErr_NoMemory();
84 }
85
86 /* Clear potential previous exception, because we explicitly check for
87 * exceptions as a loop predicate. */
88 PyErr_Clear();
calling PyErr_Clear()
89
90 /* Iterate through all keys and set lengths etc. */
91 key_it = PyObject_GetIter(key_seq);
when PyObject_GetIter() succeeds
92 i = 0;
93 while ((ckey = PyIter_Next(key_it)) != NULL) {
when PyIter_Next() retrieves a value (new ref)
taking True path
when PyIter_Next() returns NULL without setting an exception (end of iteration)
taking False path
94 char *key;
95 Py_ssize_t key_len;
96 PyObject *rkey;
97
98 assert(i < nkeys);
when considering range: 1 <= nkeys <= 0xfffffffffffffff
taking False path
99
100 if (PyErr_Occurred() || !_PylibMC_CheckKey(ckey)) {
PyErr_Occurred()
taking False path
when considering range: -0x80000000 <= value <= -1
taking False path
101 nkeys = i;
102 goto earlybird;
103 }
104
105 PyString_AsStringAndSize(ckey, &key, &key_len);
106
107 key_lens[i] = (size_t)(key_len + prefix_len);
108
109 /* Skip empty keys */
110 if (!key_lens[i])
when considering range: -0x8000000000000000 <= value <= -1
taking False path
111 continue;
112
113 /* determine rkey, the prefixed ckey */
114 if (prefix != NULL) {
when treating unknown const char * from libcpychecker/html/test/example2/pylibmc-issue-68.c:68 as non-NULL
taking True path
115 rkey = PyString_FromStringAndSize(prefix, prefix_len);
when PyString_FromStringAndSize() succeeds
116 PyString_Concat(&rkey, ckey);
117 if (rkey == NULL)
when PyString_Concat() succeeds (Py_DECREF() without deallocation on *LHS)
taking False path
118 goto earlybird;
119 rkey = PyString_FromFormat("%s%s",
when PyString_FromFormat() succeeds
120 prefix, PyString_AS_STRING(ckey));
121 } else {
122 Py_INCREF(ckey);
123 rkey = ckey;
124 }
125 Py_DECREF(ckey);
when taking True path
126
127 keys[i] = PyString_AS_STRING(rkey);
128 key_objs[i++] = rkey;
129 }
130 nkeys = i;
131 Py_XDECREF(key_it);
taking False path
when taking True path
132
133 if (nkeys == 0) {
taking False path
134 retval = PyDict_New();
135 goto earlybird;
136 } else if (PyErr_Occurred()) {
PyErr_Occurred()
taking False path
137 nkeys--;
138 goto earlybird;
139 }
140
141 /* TODO Make an iterator interface for getting each key separately.
142 *
143 * This would help large retrievals, as a single dictionary containing all
144 * the data at once isn't needed. (Should probably look into if it's even
145 * worth it.)
146 */
147 Py_BEGIN_ALLOW_THREADS;
releasing the GIL by calling PyEval_SaveThread()
148 rc = pylibmc_memcached_fetch_multi(self->mc,
149 keys, nkeys, key_lens,
150 &results, &nresults,
151 &err_func);
152 Py_END_ALLOW_THREADS;
reacquiring the GIL by calling PyEval_RestoreThread()
153
154 if (rc != MEMCACHED_SUCCESS) {
when considering value == (int)0 from libcpychecker/html/test/example2/pylibmc-issue-68.c:148
taking False path
155 PylibMC_ErrFromMemcached(self, err_func, rc);
156 goto earlybird;
157 }
158
159 retval = PyDict_New();
when PyDict_New() succeeds
160
161 for (i = 0; i < nresults; i++) {
when taking True path
162 PyObject *val, *key_obj;
163 int rc;
164
165 res = results + i;
166
167 /* Explicitly construct a key string object so that NUL-bytes and the
168 * likes can be contained within the keys (this is possible in the
169 * binary protocol.) */
170 key_obj = PyString_FromStringAndSize(memcached_result_key_value(res) + prefix_len,
when PyString_FromStringAndSize() succeeds
171 memcached_result_key_length(res) - prefix_len);
172 if (key_obj == NULL)
taking False path
173 goto unpack_error;
174
175 /* Parse out value */
176 val = _PylibMC_parse_memcached_result(res);
177 if (val == NULL)
when treating unknown struct PyObject * from libcpychecker/html/test/example2/pylibmc-issue-68.c:176 as non-NULL
taking False path
178 goto unpack_error;
179
180 rc = PyDict_SetItem(retval, key_obj, val);
when PyDict_SetItem() fails
181 Py_DECREF(key_obj);
when taking True path
182 Py_DECREF(val);
when considering range: -0x8000000000000000 <= value <= -1
taking True path
183
184 if (rc != 0)
taking True path
185 goto unpack_error;
186
187 continue;
188
189 unpack_error:
190 Py_DECREF(retval);
when taking False path
calling tp_dealloc on PyDictObject allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:159
memory deallocated here
191 break;
192 }
193
194 earlybird:
195 PyMem_Free(key_lens);
calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:77
196 PyMem_Free(keys);
calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:76
197
198 for (i = 0; i < nkeys; i++)
taking True path
taking False path
199 Py_DECREF(key_objs[i]);
when taking True path
200 PyMem_Free(key_objs);
calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:78
201
202 if (results != NULL) {
when treating unknown struct memcached_result_st * * from libcpychecker/html/test/example2/pylibmc-issue-68.c:148 as non-NULL
taking True path
203 for (i = 0; i < nresults && results != NULL; i++) {
when taking True path
taking True path
when taking False path
204 memcached_result_free(results + i);
205 }
206 PyMem_Free(results);
calling PyMem_Free on Region('heap-region-12')
207 }
208
209 /* Not INCREFing because the only two outcomes are NULL and a new dict.
210 * We're the owner of that dict already, so. */
211 return retval;
212 }
returning pointer to deallocated memory
found 11 similar trace(s) to this
File: | libcpychecker/html/test/example2/pylibmc-issue-68.c |
Function: | PylibMC_Client_get_multi |
Error: | ob_refcnt of heap-region-5 is 1 too low |
52 /* Extracted copy of PylibMC_Client_get_multi */
53 static PyObject *PylibMC_Client_get_multi(
54 PylibMC_Client *self, PyObject *args, PyObject *kwds) {
55 PyObject *key_seq, **key_objs, *retval = NULL;
56 char **keys, *prefix = NULL;
57 char *err_func = NULL;
58 memcached_result_st *res, *results = NULL;
59 int prefix_len = 0;
60 Py_ssize_t i;
61 PyObject *key_it, *ckey;
62 size_t *key_lens;
63 size_t nkeys, nresults = 0;
64 memcached_return rc;
65
66 static char *kws[] = { "keys", "key_prefix", NULL };
67
68 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s#:get_multi", kws,
when _PyArg_ParseTupleAndKeywords_SizeT() succeeds
taking False path
69 &key_seq, &prefix, &prefix_len))
70 return NULL;
71
72 if ((nkeys = (size_t)PySequence_Length(key_seq)) == -1)
when PySequence_Size() succeeds
taking False path
73 return NULL;
74
75 /* Populate keys and key_lens. */
76 keys = PyMem_New(char *, nkeys);
when considering range: 0 <= value <= 0xfffffffffffffff
taking True path
when PyMem_Malloc() succeeds
77 key_lens = PyMem_New(size_t, nkeys);
taking True path
when PyMem_Malloc() succeeds
78 key_objs = PyMem_New(PyObject *, nkeys);
taking True path
when PyMem_Malloc() succeeds
79 if (!keys || !key_lens || !key_objs) {
taking False path
taking False path
taking False path
80 PyMem_Free(keys);
81 PyMem_Free(key_lens);
82 PyMem_Free(key_objs);
83 return PyErr_NoMemory();
84 }
85
86 /* Clear potential previous exception, because we explicitly check for
87 * exceptions as a loop predicate. */
88 PyErr_Clear();
calling PyErr_Clear()
89
90 /* Iterate through all keys and set lengths etc. */
91 key_it = PyObject_GetIter(key_seq);
when PyObject_GetIter() succeeds
92 i = 0;
93 while ((ckey = PyIter_Next(key_it)) != NULL) {
when PyIter_Next() retrieves a value (new ref)
taking True path
when PyIter_Next() returns NULL without setting an exception (end of iteration)
taking False path
94 char *key;
95 Py_ssize_t key_len;
96 PyObject *rkey;
97
98 assert(i < nkeys);
when considering range: 1 <= nkeys <= 0xfffffffffffffff
taking False path
99
100 if (PyErr_Occurred() || !_PylibMC_CheckKey(ckey)) {
PyErr_Occurred()
taking False path
when considering range: -0x80000000 <= value <= -1
taking False path
101 nkeys = i;
102 goto earlybird;
103 }
104
105 PyString_AsStringAndSize(ckey, &key, &key_len);
106
107 key_lens[i] = (size_t)(key_len + prefix_len);
108
109 /* Skip empty keys */
110 if (!key_lens[i])
when considering range: -0x8000000000000000 <= value <= -1
taking False path
111 continue;
112
113 /* determine rkey, the prefixed ckey */
114 if (prefix != NULL) {
when treating unknown const char * from libcpychecker/html/test/example2/pylibmc-issue-68.c:68 as non-NULL
taking True path
115 rkey = PyString_FromStringAndSize(prefix, prefix_len);
when PyString_FromStringAndSize() succeeds
116 PyString_Concat(&rkey, ckey);
117 if (rkey == NULL)
when PyString_Concat() succeeds (Py_DECREF() without deallocation on *LHS)
taking False path
118 goto earlybird;
119 rkey = PyString_FromFormat("%s%s",
when PyString_FromFormat() succeeds
120 prefix, PyString_AS_STRING(ckey));
121 } else {
122 Py_INCREF(ckey);
123 rkey = ckey;
124 }
125 Py_DECREF(ckey);
when taking True path
126
127 keys[i] = PyString_AS_STRING(rkey);
128 key_objs[i++] = rkey;
129 }
130 nkeys = i;
131 Py_XDECREF(key_it);
taking False path
when taking True path
132
133 if (nkeys == 0) {
taking False path
134 retval = PyDict_New();
135 goto earlybird;
136 } else if (PyErr_Occurred()) {
PyErr_Occurred()
taking False path
137 nkeys--;
138 goto earlybird;
139 }
140
141 /* TODO Make an iterator interface for getting each key separately.
142 *
143 * This would help large retrievals, as a single dictionary containing all
144 * the data at once isn't needed. (Should probably look into if it's even
145 * worth it.)
146 */
147 Py_BEGIN_ALLOW_THREADS;
releasing the GIL by calling PyEval_SaveThread()
148 rc = pylibmc_memcached_fetch_multi(self->mc,
149 keys, nkeys, key_lens,
150 &results, &nresults,
151 &err_func);
152 Py_END_ALLOW_THREADS;
reacquiring the GIL by calling PyEval_RestoreThread()
153
154 if (rc != MEMCACHED_SUCCESS) {
when considering value == (int)0 from libcpychecker/html/test/example2/pylibmc-issue-68.c:148
taking False path
155 PylibMC_ErrFromMemcached(self, err_func, rc);
156 goto earlybird;
157 }
158
159 retval = PyDict_New();
when PyDict_New() succeeds
160
161 for (i = 0; i < nresults; i++) {
when taking True path
when taking False path
162 PyObject *val, *key_obj;
163 int rc;
164
165 res = results + i;
166
167 /* Explicitly construct a key string object so that NUL-bytes and the
168 * likes can be contained within the keys (this is possible in the
169 * binary protocol.) */
170 key_obj = PyString_FromStringAndSize(memcached_result_key_value(res) + prefix_len,
when PyString_FromStringAndSize() succeeds
171 memcached_result_key_length(res) - prefix_len);
172 if (key_obj == NULL)
taking False path
173 goto unpack_error;
174
175 /* Parse out value */
176 val = _PylibMC_parse_memcached_result(res);
177 if (val == NULL)
when treating unknown struct PyObject * from libcpychecker/html/test/example2/pylibmc-issue-68.c:176 as non-NULL
taking False path
178 goto unpack_error;
179
180 rc = PyDict_SetItem(retval, key_obj, val);
when PyDict_SetItem() succeeds
ob_refcnt is now refs: 0 + N where N >= 2
181 Py_DECREF(key_obj);
when taking True path
182 Py_DECREF(val);
taking True path
ob_refcnt is now refs: -1 + N where N >= 2
183
184 if (rc != 0)
taking False path
185 goto unpack_error;
186
187 continue;
188
189 unpack_error:
190 Py_DECREF(retval);
191 break;
192 }
193
194 earlybird:
195 PyMem_Free(key_lens);
calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:77
196 PyMem_Free(keys);
calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:76
197
198 for (i = 0; i < nkeys; i++)
taking True path
taking False path
199 Py_DECREF(key_objs[i]);
when taking True path
200 PyMem_Free(key_objs);
calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:78
201
202 if (results != NULL) {
when treating unknown struct memcached_result_st * * from libcpychecker/html/test/example2/pylibmc-issue-68.c:148 as non-NULL
taking True path
203 for (i = 0; i < nresults && results != NULL; i++) {
when taking True path
taking True path
when taking False path
204 memcached_result_free(results + i);
205 }
206 PyMem_Free(results);
calling PyMem_Free on Region('heap-region-6')
207 }
208
209 /* Not INCREFing because the only two outcomes are NULL and a new dict.
210 * We're the owner of that dict already, so. */
211 return retval;
212 }
ob_refcnt of heap-region-5 is 1 too low
was expecting final ob_refcnt to be N + 0 (for some unknown N)
but final ob_refcnt is N + -1
found 11 similar trace(s) to this
File: | libcpychecker/html/test/example2/pylibmc-issue-68.c |
Function: | PylibMC_Client_get_multi |
Error: | ob_refcnt of new ref from (unknown) PylibMC_ErrFromMemcached is 1 too high |
52 /* Extracted copy of PylibMC_Client_get_multi */
53 static PyObject *PylibMC_Client_get_multi(
54 PylibMC_Client *self, PyObject *args, PyObject *kwds) {
55 PyObject *key_seq, **key_objs, *retval = NULL;
56 char **keys, *prefix = NULL;
57 char *err_func = NULL;
58 memcached_result_st *res, *results = NULL;
59 int prefix_len = 0;
60 Py_ssize_t i;
61 PyObject *key_it, *ckey;
62 size_t *key_lens;
63 size_t nkeys, nresults = 0;
64 memcached_return rc;
65
66 static char *kws[] = { "keys", "key_prefix", NULL };
67
68 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s#:get_multi", kws,
when _PyArg_ParseTupleAndKeywords_SizeT() succeeds
taking False path
69 &key_seq, &prefix, &prefix_len))
70 return NULL;
71
72 if ((nkeys = (size_t)PySequence_Length(key_seq)) == -1)
when PySequence_Size() succeeds
taking False path
73 return NULL;
74
75 /* Populate keys and key_lens. */
76 keys = PyMem_New(char *, nkeys);
when considering range: 0 <= value <= 0xfffffffffffffff
taking True path
when PyMem_Malloc() succeeds
77 key_lens = PyMem_New(size_t, nkeys);
taking True path
when PyMem_Malloc() succeeds
78 key_objs = PyMem_New(PyObject *, nkeys);
taking True path
when PyMem_Malloc() succeeds
79 if (!keys || !key_lens || !key_objs) {
taking False path
taking False path
taking False path
80 PyMem_Free(keys);
81 PyMem_Free(key_lens);
82 PyMem_Free(key_objs);
83 return PyErr_NoMemory();
84 }
85
86 /* Clear potential previous exception, because we explicitly check for
87 * exceptions as a loop predicate. */
88 PyErr_Clear();
calling PyErr_Clear()
89
90 /* Iterate through all keys and set lengths etc. */
91 key_it = PyObject_GetIter(key_seq);
when PyObject_GetIter() succeeds
92 i = 0;
93 while ((ckey = PyIter_Next(key_it)) != NULL) {
when PyIter_Next() retrieves a value (new ref)
taking True path
when PyIter_Next() returns NULL without setting an exception (end of iteration)
taking False path
94 char *key;
95 Py_ssize_t key_len;
96 PyObject *rkey;
97
98 assert(i < nkeys);
when considering range: 1 <= nkeys <= 0xfffffffffffffff
taking False path
99
100 if (PyErr_Occurred() || !_PylibMC_CheckKey(ckey)) {
PyErr_Occurred()
taking False path
when considering range: -0x80000000 <= value <= -1
taking False path
101 nkeys = i;
102 goto earlybird;
103 }
104
105 PyString_AsStringAndSize(ckey, &key, &key_len);
106
107 key_lens[i] = (size_t)(key_len + prefix_len);
108
109 /* Skip empty keys */
110 if (!key_lens[i])
when considering range: -0x8000000000000000 <= value <= -1
taking False path
111 continue;
112
113 /* determine rkey, the prefixed ckey */
114 if (prefix != NULL) {
when treating unknown const char * from libcpychecker/html/test/example2/pylibmc-issue-68.c:68 as non-NULL
taking True path
115 rkey = PyString_FromStringAndSize(prefix, prefix_len);
when PyString_FromStringAndSize() succeeds
116 PyString_Concat(&rkey, ckey);
117 if (rkey == NULL)
when PyString_Concat() succeeds (Py_DECREF() without deallocation on *LHS)
taking False path
118 goto earlybird;
119 rkey = PyString_FromFormat("%s%s",
when PyString_FromFormat() succeeds
120 prefix, PyString_AS_STRING(ckey));
121 } else {
122 Py_INCREF(ckey);
123 rkey = ckey;
124 }
125 Py_DECREF(ckey);
when taking True path
126
127 keys[i] = PyString_AS_STRING(rkey);
128 key_objs[i++] = rkey;
129 }
130 nkeys = i;
131 Py_XDECREF(key_it);
taking False path
when taking True path
132
133 if (nkeys == 0) {
taking False path
134 retval = PyDict_New();
135 goto earlybird;
136 } else if (PyErr_Occurred()) {
PyErr_Occurred()
taking False path
137 nkeys--;
138 goto earlybird;
139 }
140
141 /* TODO Make an iterator interface for getting each key separately.
142 *
143 * This would help large retrievals, as a single dictionary containing all
144 * the data at once isn't needed. (Should probably look into if it's even
145 * worth it.)
146 */
147 Py_BEGIN_ALLOW_THREADS;
releasing the GIL by calling PyEval_SaveThread()
148 rc = pylibmc_memcached_fetch_multi(self->mc,
149 keys, nkeys, key_lens,
150 &results, &nresults,
151 &err_func);
152 Py_END_ALLOW_THREADS;
reacquiring the GIL by calling PyEval_RestoreThread()
153
154 if (rc != MEMCACHED_SUCCESS) {
when considering range: -0x80000000 <= value <= -1
taking True path
155 PylibMC_ErrFromMemcached(self, err_func, rc);
when PylibMC_ErrFromMemcached() succeeds
new ref from (unknown) PylibMC_ErrFromMemcached allocated at: PylibMC_ErrFromMemcached(self, err_func, rc);
ob_refcnt is now refs: 1 + N where N >= 0
156 goto earlybird;
157 }
158
159 retval = PyDict_New();
160
161 for (i = 0; i < nresults; i++) {
162 PyObject *val, *key_obj;
163 int rc;
164
165 res = results + i;
166
167 /* Explicitly construct a key string object so that NUL-bytes and the
168 * likes can be contained within the keys (this is possible in the
169 * binary protocol.) */
170 key_obj = PyString_FromStringAndSize(memcached_result_key_value(res) + prefix_len,
171 memcached_result_key_length(res) - prefix_len);
172 if (key_obj == NULL)
173 goto unpack_error;
174
175 /* Parse out value */
176 val = _PylibMC_parse_memcached_result(res);
177 if (val == NULL)
178 goto unpack_error;
179
180 rc = PyDict_SetItem(retval, key_obj, val);
181 Py_DECREF(key_obj);
182 Py_DECREF(val);
183
184 if (rc != 0)
185 goto unpack_error;
186
187 continue;
188
189 unpack_error:
190 Py_DECREF(retval);
191 break;
192 }
193
194 earlybird:
195 PyMem_Free(key_lens);
calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:77
196 PyMem_Free(keys);
calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:76
197
198 for (i = 0; i < nkeys; i++)
taking True path
taking False path
199 Py_DECREF(key_objs[i]);
when taking True path
200 PyMem_Free(key_objs);
calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:78
201
202 if (results != NULL) {
when treating unknown struct memcached_result_st * * from libcpychecker/html/test/example2/pylibmc-issue-68.c:148 as non-NULL
taking True path
203 for (i = 0; i < nresults && results != NULL; i++) {
when taking True path
taking True path
when taking False path
204 memcached_result_free(results + i);
205 }
206 PyMem_Free(results);
calling PyMem_Free on Region('heap-region-1')
207 }
208
209 /* Not INCREFing because the only two outcomes are NULL and a new dict.
210 * We're the owner of that dict already, so. */
211 return retval;
212 }
ob_refcnt of new ref from (unknown) PylibMC_ErrFromMemcached is 1 too high
was expecting final ob_refcnt to be N + 0 (for some unknown N)
but final ob_refcnt is N + 1
found 5 similar trace(s) to this
File: | libcpychecker/html/test/example2/pylibmc-issue-68.c |
Function: | PylibMC_Client_get_multi |
Error: | returning (PyObject*)NULL without setting an exception |
52 /* Extracted copy of PylibMC_Client_get_multi */
53 static PyObject *PylibMC_Client_get_multi(
54 PylibMC_Client *self, PyObject *args, PyObject *kwds) {
55 PyObject *key_seq, **key_objs, *retval = NULL;
56 char **keys, *prefix = NULL;
57 char *err_func = NULL;
58 memcached_result_st *res, *results = NULL;
59 int prefix_len = 0;
60 Py_ssize_t i;
61 PyObject *key_it, *ckey;
62 size_t *key_lens;
63 size_t nkeys, nresults = 0;
64 memcached_return rc;
65
66 static char *kws[] = { "keys", "key_prefix", NULL };
67
68 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s#:get_multi", kws,
when _PyArg_ParseTupleAndKeywords_SizeT() succeeds
taking False path
69 &key_seq, &prefix, &prefix_len))
70 return NULL;
71
72 if ((nkeys = (size_t)PySequence_Length(key_seq)) == -1)
when PySequence_Size() succeeds
taking False path
73 return NULL;
74
75 /* Populate keys and key_lens. */
76 keys = PyMem_New(char *, nkeys);
when considering range: 0 <= value <= 0xfffffffffffffff
taking True path
when PyMem_Malloc() succeeds
77 key_lens = PyMem_New(size_t, nkeys);
taking True path
when PyMem_Malloc() succeeds
78 key_objs = PyMem_New(PyObject *, nkeys);
taking True path
when PyMem_Malloc() succeeds
79 if (!keys || !key_lens || !key_objs) {
taking False path
taking False path
taking False path
80 PyMem_Free(keys);
81 PyMem_Free(key_lens);
82 PyMem_Free(key_objs);
83 return PyErr_NoMemory();
84 }
85
86 /* Clear potential previous exception, because we explicitly check for
87 * exceptions as a loop predicate. */
88 PyErr_Clear();
calling PyErr_Clear()
89
90 /* Iterate through all keys and set lengths etc. */
91 key_it = PyObject_GetIter(key_seq);
when PyObject_GetIter() succeeds
92 i = 0;
93 while ((ckey = PyIter_Next(key_it)) != NULL) {
when PyIter_Next() retrieves a value (new ref)
taking True path
when PyIter_Next() returns NULL without setting an exception (end of iteration)
taking False path
94 char *key;
95 Py_ssize_t key_len;
96 PyObject *rkey;
97
98 assert(i < nkeys);
when considering range: 1 <= nkeys <= 0xfffffffffffffff
taking False path
99
100 if (PyErr_Occurred() || !_PylibMC_CheckKey(ckey)) {
PyErr_Occurred()
taking False path
when considering range: -0x80000000 <= value <= -1
taking False path
101 nkeys = i;
102 goto earlybird;
103 }
104
105 PyString_AsStringAndSize(ckey, &key, &key_len);
106
107 key_lens[i] = (size_t)(key_len + prefix_len);
108
109 /* Skip empty keys */
110 if (!key_lens[i])
when considering range: -0x8000000000000000 <= value <= -1
taking False path
111 continue;
112
113 /* determine rkey, the prefixed ckey */
114 if (prefix != NULL) {
when treating unknown const char * from libcpychecker/html/test/example2/pylibmc-issue-68.c:68 as non-NULL
taking True path
115 rkey = PyString_FromStringAndSize(prefix, prefix_len);
when PyString_FromStringAndSize() succeeds
116 PyString_Concat(&rkey, ckey);
117 if (rkey == NULL)
when PyString_Concat() succeeds (Py_DECREF() without deallocation on *LHS)
taking False path
118 goto earlybird;
119 rkey = PyString_FromFormat("%s%s",
when PyString_FromFormat() succeeds
120 prefix, PyString_AS_STRING(ckey));
121 } else {
122 Py_INCREF(ckey);
123 rkey = ckey;
124 }
125 Py_DECREF(ckey);
when taking True path
126
127 keys[i] = PyString_AS_STRING(rkey);
128 key_objs[i++] = rkey;
129 }
130 nkeys = i;
131 Py_XDECREF(key_it);
taking False path
when taking True path
132
133 if (nkeys == 0) {
taking False path
134 retval = PyDict_New();
135 goto earlybird;
136 } else if (PyErr_Occurred()) {
PyErr_Occurred()
taking False path
137 nkeys--;
138 goto earlybird;
139 }
140
141 /* TODO Make an iterator interface for getting each key separately.
142 *
143 * This would help large retrievals, as a single dictionary containing all
144 * the data at once isn't needed. (Should probably look into if it's even
145 * worth it.)
146 */
147 Py_BEGIN_ALLOW_THREADS;
releasing the GIL by calling PyEval_SaveThread()
148 rc = pylibmc_memcached_fetch_multi(self->mc,
149 keys, nkeys, key_lens,
150 &results, &nresults,
151 &err_func);
152 Py_END_ALLOW_THREADS;
reacquiring the GIL by calling PyEval_RestoreThread()
153
154 if (rc != MEMCACHED_SUCCESS) {
when considering range: -0x80000000 <= value <= -1
taking True path
155 PylibMC_ErrFromMemcached(self, err_func, rc);
when PylibMC_ErrFromMemcached() succeeds
156 goto earlybird;
157 }
158
159 retval = PyDict_New();
160
161 for (i = 0; i < nresults; i++) {
162 PyObject *val, *key_obj;
163 int rc;
164
165 res = results + i;
166
167 /* Explicitly construct a key string object so that NUL-bytes and the
168 * likes can be contained within the keys (this is possible in the
169 * binary protocol.) */
170 key_obj = PyString_FromStringAndSize(memcached_result_key_value(res) + prefix_len,
171 memcached_result_key_length(res) - prefix_len);
172 if (key_obj == NULL)
173 goto unpack_error;
174
175 /* Parse out value */
176 val = _PylibMC_parse_memcached_result(res);
177 if (val == NULL)
178 goto unpack_error;
179
180 rc = PyDict_SetItem(retval, key_obj, val);
181 Py_DECREF(key_obj);
182 Py_DECREF(val);
183
184 if (rc != 0)
185 goto unpack_error;
186
187 continue;
188
189 unpack_error:
190 Py_DECREF(retval);
191 break;
192 }
193
194 earlybird:
195 PyMem_Free(key_lens);
calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:77
196 PyMem_Free(keys);
calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:76
197
198 for (i = 0; i < nkeys; i++)
taking True path
taking False path
199 Py_DECREF(key_objs[i]);
when taking True path
200 PyMem_Free(key_objs);
calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:78
201
202 if (results != NULL) {
when treating unknown struct memcached_result_st * * from libcpychecker/html/test/example2/pylibmc-issue-68.c:148 as non-NULL
taking True path
203 for (i = 0; i < nresults && results != NULL; i++) {
when taking True path
taking True path
when taking False path
204 memcached_result_free(results + i);
205 }
206 PyMem_Free(results);
calling PyMem_Free on Region('heap-region-1')
207 }
208
209 /* Not INCREFing because the only two outcomes are NULL and a new dict.
210 * We're the owner of that dict already, so. */
211 return retval;
212 }
returning (PyObject*)NULL without setting an exception
found 5 similar trace(s) to this