Fix wrapping of string with control characters

Fix wrapping of string constants containing bytes 0-8, 11, 12 or 14-31
followed by a digit '0' to '7'.  We were emitting these bytes as a one
or two character octal escape sequence which when interpreted would
include the following character.
This commit is contained in:
Olly Betts 2024-08-01 14:36:43 +12:00
parent 44990e2562
commit 8d1ac40dc6
4 changed files with 41 additions and 6 deletions

View File

@ -7,6 +7,12 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.3.0 (in progress)
===========================
2024-08-01: olly
Fix wrapping of string constants containing bytes 0-8, 11, 12 or
14-31 followed by a digit '0' to '7'. We were emitting these bytes
as a one or two character octal escape sequence which when
interpreted would include the following character.
2024-07-27: olly
#2087 Fix parsing of `noexcept` on a function pointer type used
as the type of a function parameter. We currently generate

View File

@ -0,0 +1,18 @@
<?php
require "tests.php";
// No new functions
check::functions(array());
// New classes
check::classes(array('string_constants', 'things'));
// New vars
check::globals(array('AA3', 'EE3', 'ES3', 'QQ3', 'SS3', 'XX3', 'ZS3'));
check::equal(string_constants::QQ1, "\01000!");
check::equal(string_constants::QQ2, "\01000!");
check::equal(QQ3_get(), "\01000!");
$t = new things();
check::equal($t->defarguments7(), "\01000!");
check::done();

View File

@ -18,6 +18,7 @@
#define XX1 "\x57\x58\x59"
#define ZS1 "\0"
#define ES1 ""
#define QQ1 "\b00!"
%}
%constant SS2="ÆÎOU\n";
%constant AA2="A\rB\nC";
@ -25,6 +26,7 @@
%constant XX2="\x57\x58\x59";
%constant ZS2="\0";
%constant ES2="";
%constant QQ2="\b00!";
%inline %{
static const char *SS3 = "ÆÎOU\n";
@ -33,6 +35,7 @@ static const char *EE3 = "\124\125\126";
static const char *XX3 = "\x57\x58\x59";
static const char *ZS3 = "\0";
static const char *ES3 = "";
static const char *QQ3 = "\b00!";
struct things {
const char * defarguments1(const char *SS4 = "ÆÎOU\n") { return SS4; }
const char * defarguments2(const char *AA4 = "A\rB\nC") { return AA4; }
@ -40,5 +43,6 @@ struct things {
const char * defarguments4(const char *XX4 = "\x57\x58\x59") { return XX4; }
const char * defarguments5(const char *ZS4 = "\0") { return ZS4; }
const char * defarguments6(const char *ES4 = "") { return ES4; }
const char * defarguments7(const char *QQ4 = "\b00!") { return QQ4; }
};
%}

View File

@ -357,11 +357,9 @@ int Swig_storage_isstatic(Node *n) {
* ----------------------------------------------------------------------------- */
String *Swig_string_escape(String *s) {
String *ns;
int c;
ns = NewStringEmpty();
while ((c = Getc(s)) != EOF) {
String *ns = NewStringEmpty();
int c = Getc(s);
while (c != EOF) {
if (c == '\n') {
Printf(ns, "\\n");
} else if (c == '\r') {
@ -377,12 +375,21 @@ String *Swig_string_escape(String *s) {
} else if (c == ' ') {
Putc(c, ns);
} else if (!isgraph(c)) {
int next_c = Getc(s);
if (c < 0)
c += UCHAR_MAX + 1;
Printf(ns, "\\%o", c);
if (next_c >= '0' && next_c < '8') {
/* We need to emit 3 octal digits. */
Printf(ns, "\\%03o", c);
} else {
Printf(ns, "\\%o", c);
}
c = next_c;
continue;
} else {
Putc(c, ns);
}
c = Getc(s);
}
return ns;
}