Page MenuHomeFreeBSD

D56758.1794600670.diff
No OneTemporary

Authored By
Unknown
Size
3 KB
Referenced Files
None
Subscribers
None

D56758.1794600670.diff

diff --git a/lib/libc/iconv/bsd_iconv.c b/lib/libc/iconv/bsd_iconv.c
--- a/lib/libc/iconv/bsd_iconv.c
+++ b/lib/libc/iconv/bsd_iconv.c
@@ -69,6 +69,12 @@
}
handle->cv_shared->ci_discard_ilseq = strcasestr(out, "//IGNORE");
+ /*
+ * Restore behavior with do_conv() failings to the GNU compatible one.
+ * The old behavior isn't technically POSIX conformant, but a number of
+ * high profile applications depend on it.
+ */
+ handle->cv_shared->ci_ilseq_invalid = true;
return ((iconv_t)(void *)handle);
}
diff --git a/lib/libc/iconv/iconv.3 b/lib/libc/iconv/iconv.3
--- a/lib/libc/iconv/iconv.3
+++ b/lib/libc/iconv/iconv.3
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd August 4, 2014
+.Dd May 1, 2026
.Dt ICONV 3
.Os
.Sh NAME
@@ -133,8 +133,18 @@
If the string pointed to by
.Fa *src
contains a character which is valid under the source codeset but
-can not be converted to the destination codeset,
-the character is replaced by an
+cannot be converted to the destination codeset, the exact behavior depends on
+the current setting of the
+.Dv ICONV_SET_ILSEQ_INVALID
+.Xr iconvctl 3 .
+By default, the
+.Fn iconv
+function handles such characters by halting the conversion at the invalid
+sequence and returning
+.Er EILSEQ .
+If
+.Dv ICONV_SET_ILSEQ_INVALID
+is set to 0, then the character is replaced by an
.Dq invalid character
which depends on the destination codeset, e.g.,
.Sq \&? ,
@@ -291,14 +301,26 @@
.Xr iconvlist 3
.Sh STANDARDS
The
-.Fn iconv_open ,
-.Fn iconv_close ,
+.Fn iconv_open
and
-.Fn iconv
+.Fn iconv_close
functions conform to
.St -p1003.1-2008 .
.Pp
The
+.Fn iconv
+function conforms to
+.St -p1003.1-2008
+only when the
+.Dv ICONV_SET_ILSEQ_INVALID
+.Xr iconvctl 3
+is set to 0.
+The default behavior to return an
+.Er EILSEQ
+error and halt rather than return the number of invalid characters does not
+conform to the specification.
+.Pp
+The
.Fn iconv_open_into
function is a GNU-specific extension and it is not part of any standard,
thus its use may break portability.
diff --git a/lib/libc/tests/iconv/iconv_test.c b/lib/libc/tests/iconv/iconv_test.c
--- a/lib/libc/tests/iconv/iconv_test.c
+++ b/lib/libc/tests/iconv/iconv_test.c
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
+#include <errno.h>
#include <iconv.h>
#include <atf-c.h>
@@ -44,9 +45,46 @@
iconv_close(cd);
}
+ATF_TC_WITHOUT_HEAD(test_ilseq_out);
+ATF_TC_BODY(test_ilseq_out, tc)
+{
+ iconv_t cd;
+ char str[] = "при";
+ char outbuf[8];
+ char *inptr, *outptr;
+ size_t insz, outsz;
+ int res;
+
+ cd = iconv_open("US-ASCII", "UTF-8");
+ ATF_REQUIRE(cd != (iconv_t)-1);
+
+ inptr = &str[0];
+ insz = sizeof(str) - 1;
+ outptr = &outbuf[0];
+ outsz = sizeof(outbuf);
+
+ /* Default: return EILSEQ, in string has not advanced. */
+ res = iconv(cd, &inptr, &insz, &outptr, &outsz);
+ ATF_REQUIRE(res == -1);
+ ATF_REQUIRE(errno == EILSEQ);
+ ATF_REQUIRE(inptr == &str[0]);
+ ATF_REQUIRE(insz == sizeof(str) - 1);
+
+ /* POSIX: return # invalid, in string does advance. */
+ set_ilseq_invalid(cd, 0);
+ res = iconv(cd, &inptr, &insz, &outptr, &outsz);
+ ATF_REQUIRE(res == 3);
+ ATF_REQUIRE(inptr == &str[sizeof(str) - 1]);
+ ATF_REQUIRE(insz == 0);
+
+ iconv_close(cd);
+}
+
+
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, test_ignore_precedence);
+ ATF_TP_ADD_TC(tp, test_ilseq_out);
return (atf_no_error());
}

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 13, 8:11 PM (16 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41701911
Default Alt Text
D56758.1794600670.diff (3 KB)

Event Timeline