Repository: pandas-dev/pandas
File: pandas/_libs/src/vendored/ujson/python/objToJSON.c (C)

Code before:
    tc->prv = NULL;
  }
}

static const char *Object_getStringValue(JSOBJ obj, JSONTypeContext *tc,
                                         size_t *_outLen) {
  return GET_TC(tc)->PyTypeToUTF8(obj, tc, _outLen);
}

static JSINT64 Object_getLongValue(JSOBJ Py_UNUSED(obj), JSONTypeContext *tc) {
  return GET_TC(tc)->longValue;
}

static double Object_getDoubleValue(JSOBJ Py_UNUSED(obj), JSONTypeContext *tc) {
  return GET_TC(tc)->doubleValue;
}

static const char *Object_getBigNumStringValue(JSOBJ obj, JSONTypeContext *tc,
                                               size_t *_outLen) {
  PyObject *repr = PyObject_Str(obj);
  const char *str = PyUnicode_AsUTF8AndSize(repr, (Py_ssize_t *)_outLen);
  char *bytes = PyObject_Malloc(*_outLen + 1);
  memcpy(bytes, str, *_outLen + 1);
  GET_TC(tc)->cStr = bytes;

  Py_DECREF(repr);

  return GET_TC(tc)->cStr;
}

static void Object_releaseObject(JSOBJ _obj) { Py_DECREF((PyObject *)_obj); }

static void Object_iterBegin(JSOBJ obj, JSONTypeContext *tc) {
  GET_TC(tc)->iterBegin(obj, tc);
}

static int Object_iterNext(JSOBJ obj, JSONTypeContext *tc) {
  return GET_TC(tc)->iterNext(obj, tc);
}

static void Object_iterEnd(JSOBJ obj, JSONTypeContext *tc) {
  GET_TC(tc)->iterEnd(obj, tc);
}

static JSOBJ Object_iterGetValue(JSOBJ obj, JSONTypeContext *tc) {
  return GET_TC(tc)->iterGetValue(obj, tc);
}

static const char *Object_iterGetName(JSOBJ obj, JSONTypeContext *tc,
                                      size_t *outLen) {
  return GET_TC(tc)->iterGetName(obj, tc, outLen);

Review comment (bug):
Can you double check the paths that actually hit this? Right now it seems like we either implicitly have some kind of relation with the types allocate storage for the struct member and this function getting called, or we have undefined behavior when always calling free here, if the type doesn't allocate this in the first place


Code after:
  }

  tc->type = JT_OBJECT;
  pc->iterBegin = Dir_iterBegin;
  pc->iterEnd = Dir_iterEnd;
  pc->iterNext = Dir_iterNext;
  pc->iterGetValue = Dir_iterGetValue;
  pc->iterGetName = Dir_iterGetName;
  return;

INVALID:
  tc->type = JT_INVALID;
  PyObject_Free(tc->prv);
  tc->prv = NULL;
  return;
}

static void Object_endTypeContext(JSOBJ Py_UNUSED(obj), JSONTypeContext *tc) {
  if (tc->prv) {
    Py_XDECREF(GET_TC(tc)->newObj);
    GET_TC(tc)->newObj = NULL;
    NpyArr_freeLabels(GET_TC(tc)->rowLabels, GET_TC(tc)->rowLabelsLen);
    GET_TC(tc)->rowLabels = NULL;
    NpyArr_freeLabels(GET_TC(tc)->columnLabels, GET_TC(tc)->columnLabelsLen);
    GET_TC(tc)->columnLabels = NULL;
    PyObject_Free(GET_TC(tc)->cStr);
    GET_TC(tc)->cStr = NULL;
    PyObject_Free(tc->prv);
    tc->prv = NULL;
  }
}

static const char *Object_getStringValue(JSOBJ obj, JSONTypeContext *tc,
                                         size_t *_outLen) {
  return GET_TC(tc)->PyTypeToUTF8(obj, tc, _outLen);
}

static JSINT64 Object_getLongValue(JSOBJ Py_UNUSED(obj), JSONTypeContext *tc) {
  return GET_TC(tc)->longValue;
}

static double Object_getDoubleValue(JSOBJ Py_UNUSED(obj), JSONTypeContext *tc) {
  return GET_TC(tc)->doubleValue;
}

static const char *Object_getBigNumStringValue(JSOBJ obj, JSONTypeContext *tc,
                                               size_t *_outLen) {
  PyObject *repr = PyObject_Str(obj);
  const char *str = PyUnicode_AsUTF8AndSize(repr, (Py_ssize_t *)_outLen);
  char *bytes = PyObject_Malloc(*_outLen + 1);
  memcpy(bytes, str, *_outLen + 1);