File: gitdb/_fun.c
Function: PackIndexFile_sha_to_index
Error: ob_refcnt of '*get_sha' is 1 too high
3 static PyObject *PackIndexFile_sha_to_index(PyObject *self, PyObject *args)
4 {
5 	const unsigned char *sha;
6 	const unsigned int sha_len;
7 	
8 	// Note: self is only set if we are a c type. We emulate an instance method, 
9 	// hence we have to get the instance as 'first' argument
10 	
11 	// get instance and sha
12 	PyObject* inst = 0;
13 	if (!PyArg_ParseTuple(args, "Os#", &inst, &sha, &sha_len))
14 		return NULL;
when PyArg_ParseTuple() succeeds
taking False path
15 	
16 	if (sha_len != 20) {
17 		PyErr_SetString(PyExc_ValueError, "Sha is not 20 bytes long");
when considering value == (int)20 from gitdb/_fun.c:14
taking False path
18 		return NULL;
19 	}
20 	
21 	if( !inst){
22 		PyErr_SetString(PyExc_ValueError, "Cannot be called without self");
taking False path
23 		return NULL;
24 	}
25 	
26 	// read lo and hi bounds
27 	PyObject* fanout_table = PyObject_GetAttrString(inst, "_fanout_table");
28 	if (!fanout_table){
when PyObject_GetAttrString() succeeds
29 		PyErr_SetString(PyExc_ValueError, "Couldn't obtain fanout table");
taking False path
30 		return NULL;
31 	}
32 	
33 	unsigned int lo = 0, hi = 0;
34 	if (sha[0]){
35 		PyObject* item = PySequence_GetItem(fanout_table, (const Py_ssize_t)(sha[0]-1));
when treating unknown const char * from gitdb/_fun.c:14 as non-NULL
when considering value == (const unsigned char)0 from gitdb/_fun.c:35
taking False path
36 		lo = PyInt_AS_LONG(item);
37 		Py_DECREF(item);
38 	}
39 	PyObject* item = PySequence_GetItem(fanout_table, (const Py_ssize_t)sha[0]);
40 	hi = PyInt_AS_LONG(item);
when PySequence_GetItem() succeeds
41 	Py_DECREF(item);
42 	item = 0;
when taking True path
43 	
44 	Py_DECREF(fanout_table);
45 	
when taking True path
46 	// get sha query function
47 	PyObject* get_sha = PyObject_GetAttrString(inst, "sha");
48 	if (!get_sha){
when PyObject_GetAttrString() succeeds
new ref from call to PyObject_GetAttrString allocated at: 	PyObject* get_sha = PyObject_GetAttrString(inst, "sha");
ob_refcnt is now refs: 1 + N where N >= 0
49 		PyErr_SetString(PyExc_ValueError, "Couldn't obtain sha method");
taking False path
50 		return NULL;
51 	}
52 	
53 	PyObject *sha_str = 0;
54 	while (lo < hi) {
55 		const int mid = (lo + hi)/2;
when considering range: 1 <= hi <= 0xffffffff
taking True path
56 		sha_str = PyObject_CallFunction(get_sha, "i", mid);
57 		if (!sha_str) {
when PyObject_CallFunction() fails
58 			return NULL;
taking True path
59 		}
60 		
61 		// we really trust that string ... for speed 
62 		const int cmp = memcmp(PyString_AS_STRING(sha_str), sha, 20);
63 		Py_DECREF(sha_str);
64 		sha_str = 0;
65 		
66 		if (cmp < 0){
67 			lo = mid + 1;
68 		}
69 		else if (cmp > 0) {
70 			hi = mid;
71 		}
72 		else {
73 			Py_DECREF(get_sha);
74 			return PyInt_FromLong(mid);
75 		}// END handle comparison
76 	}// END while lo < hi
77 	
78 	// nothing found, cleanup
79 	Py_DECREF(get_sha);
80 	Py_RETURN_NONE;
81 }
82 
ob_refcnt of '*get_sha' is 1 too high was expecting final ob_refcnt to be N + 0 (for some unknown N) but final ob_refcnt is N + 1