High severityNVD Advisory· Published Aug 26, 2012· Updated Apr 29, 2026
CVE-2012-1176
CVE-2012-1176
Description
Buffer overflow in the fribidi_utf8_to_unicode function in PyFriBidi before 0.11.0 allows remote attackers to cause a denial of service (application crash) via a 4-byte utf-8 sequence.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
pyfribidiPyPI | < 0.11.0 | 0.11.0 |
Affected products
1Patches
1d2860c655357refactor pyfribidi.c module
5 files changed · +127 −310
MANIFEST.in+1 −1 modified@@ -160,7 +160,7 @@ include fribidi-src/test/test_UTF-8_reordernsm.input include fribidi-src/test/test_UTF-8_reordernsm.reference include fribidi_systray.py include pyfribidi.c -include pyfribidi.h +include pyfribidi.py include pyfribidi2.py include setup.cfg include setup.py
pyfribidi.c+90 −241 modified@@ -17,267 +17,116 @@ /* Copyright (C) 2005,2006,2010 Yaacov Zamir, Nir Soffer */ -/* FriBidi python binding: - - Install: - python setup.py install - - */ -#include <Python.h> /* must be first */ +#include <Python.h> #include <fribidi.h> -#undef _POSIX_C_SOURCE - -#include "pyfribidi.h" -#define MAX_STR_LEN 65000 static PyObject * -_pyfribidi_log2vis (PyObject * self, PyObject * args, PyObject * kw) +unicode_log2vis (PyUnicodeObject* string, + FriBidiParType base_direction, int clean, int reordernsm) { - PyObject *logical = NULL; /* input unicode or string object */ - FriBidiParType base = FRIBIDI_TYPE_RTL; /* optional direction */ - const char *encoding = "utf-8"; /* optional input string encoding */ - int clean = 0; /* optional flag to clean the string */ - int reordernsm = 1; /* optional flag to allow reordering of non spacing marks*/ - - static char *kwargs[] = - { "logical", "base_direction", "encoding", "clean", "reordernsm", NULL }; - - if (!PyArg_ParseTupleAndKeywords (args, kw, "O|isii", kwargs, - &logical, &base, &encoding, &clean, &reordernsm)) - return NULL; - - /* Validate base */ - - if (!(base == FRIBIDI_TYPE_RTL || - base == FRIBIDI_TYPE_LTR || base == FRIBIDI_TYPE_ON)) - return PyErr_Format (PyExc_ValueError, - "invalid value %d: use either RTL, LTR or ON", - base); - - /* Check object type and delegate to one of the log2vis functions */ - - if (PyUnicode_Check (logical)) - return log2vis_unicode (logical, base, clean, reordernsm); - else if (PyString_Check (logical)) - return log2vis_encoded_string (logical, encoding, base, clean, reordernsm); - else - return PyErr_Format (PyExc_TypeError, - "expected unicode or str, not %s", - logical->ob_type->tp_name); + int i; + int length = string->length; + FriBidiChar *logical = NULL; /* input fribidi unicode buffer */ + FriBidiChar *visual = NULL; /* output fribidi unicode buffer */ + FriBidiStrIndex new_len = 0; /* length of the UTF-8 buffer */ + PyUnicodeObject *result = NULL; + + /* Allocate fribidi unicode buffers + TODO - Don't copy strings if sizeof(FriBidiChar) == sizeof(Py_UNICODE) + */ + + logical = PyMem_New (FriBidiChar, length + 1); + if (logical == NULL) { + PyErr_NoMemory(); + goto cleanup; + } + + visual = PyMem_New (FriBidiChar, length + 1); + if (visual == NULL) { + PyErr_NoMemory(); + goto cleanup; + } + + for (i=0; i<length; ++i) { + logical[i] = string->str[i]; + } + + /* Convert to unicode and order visually */ + fribidi_set_reorder_nsm(reordernsm); + + if (!fribidi_log2vis (logical, length, &base_direction, visual, + NULL, NULL, NULL)) { + + PyErr_SetString (PyExc_RuntimeError, + "fribidi failed to order string"); + goto cleanup; + } + + /* Cleanup the string if requested */ + if (clean) { + length = fribidi_remove_bidi_marks (visual, length, NULL, NULL, NULL); + } + + result = (PyUnicodeObject*) PyUnicode_FromUnicode(NULL, length); + if (result == NULL) { + goto cleanup; + } + + for (i=0; i<length; ++i) { + result->str[i] = visual[i]; + } + + cleanup: + /* Delete unicode buffers */ + PyMem_Del (logical); + PyMem_Del (visual); + + return (PyObject *)result; } -/* - log2vis_unicode - reorder unicode string visually - - Return value: new reference - - Return Python unicode object ordered visually or NULL if an exception - was raised. - - Since Python and fribidi don't now know each other unicode format, - encode input string as utf-8 and invoke log2vis_utf8. - - Arguments: - - - unicode: Python unicode object - - base_direction: input string base direction, e.g right to left -*/ - static PyObject * -log2vis_unicode (PyObject * unicode, FriBidiParType base_direction, int clean, int reordernsm) +_pyfribidi_log2vis (PyObject * self, PyObject * args, PyObject * kw) { - PyObject *logical = NULL; /* input string encoded in utf-8 */ - PyObject *visual = NULL; /* output string encoded in utf-8 */ - PyObject *result = NULL; /* unicode output string */ - - int length = PyUnicode_GET_SIZE (unicode); - - logical = PyUnicode_AsUTF8String (unicode); - if (logical == NULL) - goto cleanup; - - visual = log2vis_utf8 (logical, length, base_direction, clean, reordernsm); - if (visual == NULL) - goto cleanup; - - result = PyUnicode_DecodeUTF8 (PyString_AS_STRING (visual), - PyString_GET_SIZE (visual), "strict"); - - cleanup: - Py_XDECREF (logical); - Py_XDECREF (visual); - - return result; + PyUnicodeObject *logical = NULL; /* input unicode or string object */ + FriBidiParType base = FRIBIDI_TYPE_RTL; /* optional direction */ + int clean = 0; /* optional flag to clean the string */ + int reordernsm = 1; /* optional flag to allow reordering of non spacing marks*/ + + static char *kwargs[] = + { "logical", "base_direction", "clean", "reordernsm", NULL }; + + if (!PyArg_ParseTupleAndKeywords (args, kw, "U|iii", kwargs, + &logical, &base, &clean, &reordernsm)) { + return NULL; + } + + /* Validate base */ + + if (!(base == FRIBIDI_TYPE_RTL + || base == FRIBIDI_TYPE_LTR + || base == FRIBIDI_TYPE_ON)) { + return PyErr_Format (PyExc_ValueError, + "invalid value %d: use either RTL, LTR or ON", + base); + } + + return unicode_log2vis (logical, base, clean, reordernsm); } -/* - log2vis_encoded_string - reorder encoded string visually - - Return value: new reference - - Return Python string object ordered visually or NULL if an exception - was raised. The returned string use the same encoding. - - Invoke either log2vis_utf8 or log2vis_unicode. - - - string: Python string object using encoding - - encoding: string encoding, any encoding name known to Python - - base_direction: input string base direction, e.g right to left - */ - -static PyObject * -log2vis_encoded_string (PyObject * string, const char *encoding, - FriBidiParType base_direction, int clean, int reordernsm) -{ - PyObject *logical = NULL; /* logical unicode object */ - PyObject *result = NULL; /* output string object */ - - /* Always needed for the string length */ - logical = PyUnicode_Decode (PyString_AS_STRING (string), - PyString_GET_SIZE (string), - encoding, "strict"); - if (logical == NULL) - return NULL; - - if (strcmp (encoding, "utf-8") == 0) - /* Shortcut for utf8 strings (little faster) */ - result = log2vis_utf8 (string, - PyUnicode_GET_SIZE (logical), - base_direction, clean, reordernsm); - else - { - /* Invoke log2vis_unicode and encode back to encoding */ - - PyObject *visual = log2vis_unicode (logical, base_direction, clean, reordernsm); - - if (visual) - { - result = PyUnicode_Encode (PyUnicode_AS_UNICODE - (visual), - PyUnicode_GET_SIZE (visual), - encoding, "strict"); - Py_DECREF (visual); - } - } - - Py_DECREF (logical); - - return result; -} - -/* - log2vis_utf8 - reorder string visually - - Return value: new reference - - Return Python string object ordered visually or NULL if an exception - was raised. - - Arguments: - - - string: Python string object using utf-8 encoding - - unicode_length: number of characters in string. This is not the - number of bytes in the string, which may be much bigger than the - number of characters, because utf-8 uses 1-4 bytes per character. - - base_direction: input string base direction, e.g right to left -*/ - -static PyObject * -log2vis_utf8 (PyObject * string, int unicode_length, - FriBidiParType base_direction, int clean, int reordernsm) -{ - FriBidiChar *logical = NULL; /* input fribidi unicode buffer */ - FriBidiChar *visual = NULL; /* output fribidi unicode buffer */ - char *visual_utf8 = NULL; /* output fribidi UTF-8 buffer */ - FriBidiStrIndex new_len = 0; /* length of the UTF-8 buffer */ - PyObject *result = NULL; /* failure */ - - /* Allocate fribidi unicode buffers */ - - logical = PyMem_New (FriBidiChar, unicode_length + 1); - if (logical == NULL) - { - PyErr_SetString (PyExc_MemoryError, - "failed to allocate unicode buffer"); - goto cleanup; - } - - visual = PyMem_New (FriBidiChar, unicode_length + 1); - if (visual == NULL) - { - PyErr_SetString (PyExc_MemoryError, - "failed to allocate unicode buffer"); - goto cleanup; - } - - /* Convert to unicode and order visually */ - fribidi_set_reorder_nsm(reordernsm); - fribidi_utf8_to_unicode (PyString_AS_STRING (string), - PyString_GET_SIZE (string), logical); - - if (!fribidi_log2vis (logical, unicode_length, &base_direction, visual, - NULL, NULL, NULL)) - { - PyErr_SetString (PyExc_RuntimeError, - "fribidi failed to order string"); - goto cleanup; - } - - /* Cleanup the string if requested */ - if (clean) - fribidi_remove_bidi_marks (visual, unicode_length, NULL, NULL, NULL); - - /* Allocate fribidi UTF-8 buffer */ - - visual_utf8 = PyMem_New(char, (unicode_length * 4)+1); - if (visual_utf8 == NULL) - { - PyErr_SetString (PyExc_MemoryError, - "failed to allocate UTF-8 buffer"); - goto cleanup; - } - - /* Encode the reordered string and create result string */ - - new_len = fribidi_unicode_to_utf8 (visual, unicode_length, visual_utf8); - - result = PyString_FromStringAndSize (visual_utf8, new_len); - if (result == NULL) - /* XXX does it raise any error? */ - goto cleanup; - - cleanup: - /* Delete unicode buffers */ - PyMem_Del (logical); - PyMem_Del (visual); - PyMem_Del (visual_utf8); - - return result; -} static PyMethodDef PyfribidiMethods[] = { - {"log2vis", (PyCFunction) _pyfribidi_log2vis, - METH_VARARGS | METH_KEYWORDS, - _pyfribidi_log2vis__doc__}, + {"log2vis", (PyCFunction) _pyfribidi_log2vis, METH_VARARGS | METH_KEYWORDS, NULL}, {NULL, NULL, 0, NULL} }; + PyMODINIT_FUNC -initpyfribidi (void) +init_pyfribidi (void) { - PyObject *module; - - /* XXX What should be done if we fail here? */ - - module = Py_InitModule3 ("pyfribidi", PyfribidiMethods, - _pyfribidi__doc__); - + PyObject *module = Py_InitModule ("_pyfribidi", PyfribidiMethods); PyModule_AddIntConstant (module, "RTL", (long) FRIBIDI_TYPE_RTL); PyModule_AddIntConstant (module, "LTR", (long) FRIBIDI_TYPE_LTR); PyModule_AddIntConstant (module, "ON", (long) FRIBIDI_TYPE_ON); - - PyModule_AddStringConstant (module, "__author__", - "Yaacov Zamir and Nir Soffer"); }
pyfribidi.h+0 −66 removed@@ -1,66 +0,0 @@ - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* Copyright (C) 2005,2006,2010 Yaacov Zamir, Nir Soffer */ - -/* FriBidi python binding: - - Install: - python setup.py install - - */ - -#ifndef __PYFRIBIDI_H__ -#define __PYFRIBIDI_H__ - -static PyObject *_pyfribidi_log2vis (PyObject * self, PyObject * args, - PyObject * kw); - -static PyObject *log2vis_unicode (PyObject * unicode, - FriBidiParType base_direction, int clean, int reordernsm); - -static PyObject *log2vis_encoded_string (PyObject * string, - const char *encoding, - FriBidiParType base_direction, int clean, int reordernsm); - -static PyObject *log2vis_utf8 (PyObject * string, int unicode_length, - FriBidiParType base_direction, int clean, int reordernsm); - -PyMODINIT_FUNC initpyfribidi (void); - -PyDoc_STRVAR (_pyfribidi__doc__, - "simple Python binding for fribidi.\n\n" - "pyfribidi uses libfribidi to order text visually using the unicode\n" - "algorithm. pyfribidi can also convert text from visual order to\n" - "logical order, but the conversion may be wrong in certain cases.\n"); - -/* Based on fribidi-0.10.7 README */ -PyDoc_STRVAR (_pyfribidi_log2vis__doc__, - "log2vis(logical, base_direction=RTL , encoding='utf-8') -> visual\n\n" - "Return string reordered visually according to base direction.\n" - "Return the same type of input string, either unicode or string using\n" - "encoding.\n\n" - "Note that this function does not handle line breaking. You should\n" - "call log2vis with each line.\n\n" - "Arguments:\n\n" - "- logical: unicode or encoded string\n" - "- base_direction: optional logical base direction. Accepts one of\n" - " the constants LTR, RTL or ON, defined in this module. ON calculate\n" - " the base direction according to the BiDi algorithm.\n" - "- encoding: optional string encoding (ignored for unicode input)\n"); - -#endif /* __PYFRIBIDI_H__ */
pyfribidi.py+34 −0 added@@ -0,0 +1,34 @@ +"""simple Python binding for fribidi. + +pyfribidi uses libfribidi to order text visually using the unicode +algorithm. pyfribidi can also convert text from visual order to +logical order, but the conversion may be wrong in certain cases. +""" + +from _pyfribidi import LTR, ON, RTL, log2vis as _log2vis + +def log2vis(logical, base_direction=RTL, encoding="utf-8", clean=False, reordernsm=True): + """ + Return string reordered visually according to base direction. + Return the same type of input string, either unicode or string using + encoding. + + Note that this function does not handle line breaking. You should + call log2vis with each line. + + Arguments: + - logical: unicode or encoded string + - base_direction: optional logical base direction. Accepts one of + the constants LTR, RTL or ON, defined in this module. ON calculate + the base direction according to the BiDi algorithm. + - encoding: optional string encoding (ignored for unicode input) + """ + + if not isinstance(logical, unicode): + logical = unicode(logical, encoding) + else: + encoding = None + res = _log2vis(logical, base_direction=base_direction, clean=clean, reordernsm=reordernsm) + if encoding: + return res.encode(encoding) + return res
setup.py+2 −2 modified@@ -94,9 +94,9 @@ def read_long_description(): license="GPL", cmdclass={'build_ext': my_build_ext}, long_description=read_long_description(), - py_modules=["pyfribidi2"], + py_modules=["pyfribidi", "pyfribidi2"], ext_modules=[Extension( - name='pyfribidi', + name='_pyfribidi', sources=['pyfribidi.c'] + lib_sources, define_macros=define_macros, libraries=libraries,
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
18- github.com/advisories/GHSA-6476-g47x-h3c7ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2012-1176ghsaADVISORY
- bugs.debian.org/cgi-bin/bugreport.cginvdWEB
- groups.google.com/group/linux.debian.bugs.dist/browse_thread/thread/aacd036037217998/8d095f85f3665bffnvdWEB
- lists.fedoraproject.org/pipermail/package-announce/2012-March/075293.htmlnvdWEB
- lists.fedoraproject.org/pipermail/package-announce/2012-March/076038.htmlnvdWEB
- lists.fedoraproject.org/pipermail/package-announce/2012-March/076053.htmlnvdWEB
- www.openwall.com/lists/oss-security/2012/03/14/4nvdWEB
- www.openwall.com/lists/oss-security/2012/03/14/9nvdWEB
- bugzilla.redhat.com/show_bug.cginvdWEB
- bugzilla.wikimedia.org/show_bug.cginvdWEB
- exchange.xforce.ibmcloud.com/vulnerabilities/74001nvdWEB
- github.com/pediapress/pyfribidi/commit/d2860c655357975e7b32d84e6b45e98f0dcecd7anvdWEB
- github.com/pediapress/pyfribidi/issues/2ghsaWEB
- github.com/pediapress/pyfribidi/issues/2%29:nvdWEB
- github.com/pypa/advisory-database/tree/main/vulns/pyfribidi/PYSEC-2012-11.yamlghsaWEB
- web.archive.org/web/20200228170815/http://www.securityfocus.com/bid/52451ghsaWEB
- www.securityfocus.com/bid/52451nvd
News mentions
0No linked articles in our index yet.