Skip to content

Commit b90fcfc

Browse files
committed
dxf: fix dxf_fixup_string logic
Fixes most parts of GH #986 (thanks to @vagran/Artyom Lebedev). Remaining is proper utf8-len splitting. not 250 bytes but runes. This needs to be done by converting overlong strings to UCS-2, split them at 250 and then output them as UTF-8.
1 parent f122b04 commit b90fcfc

File tree

1 file changed

+41
-51
lines changed

1 file changed

+41
-51
lines changed

src/out_dxf.c

Lines changed: 41 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,7 @@ static int dxf_3dsolid (Bit_Chain *restrict dat,
6969
const Dwg_Object *restrict obj,
7070
Dwg_Entity_3DSOLID *restrict _obj);
7171
static void dxf_fixup_string (Bit_Chain *restrict dat, char *restrict str,
72-
const int opts, const int dxf,
73-
const int dxfcont);
72+
const int opts, const int dxf);
7473
static void dxf_CMC (Bit_Chain *restrict dat, Dwg_Color *restrict color,
7574
const int dxf, const int opt);
7675

@@ -90,14 +89,12 @@ static void dxf_CMC (Bit_Chain *restrict dat, Dwg_Color *restrict color,
9089

9190
#define VALUE_TV(value, dxf) \
9291
{ \
93-
GROUP (dxf); \
94-
dxf_fixup_string (dat, (char *)value, 1, dxf, dxf); \
92+
dxf_fixup_string (dat, (char *)value, 1, dxf); \
9593
}
9694
#define VALUE_TV0(value, dxf) \
9795
if (dxf && value && *value) \
9896
{ \
99-
GROUP (dxf); \
100-
dxf_fixup_string (dat, (char *)value, 1, dxf, dxf); \
97+
dxf_fixup_string (dat, (char *)value, 1, dxf); \
10198
}
10299
// in_json writes all strings as TV, in_dxf and decode not.
103100
#define VALUE_TU(wstr, dxf) \
@@ -109,23 +106,15 @@ static void dxf_CMC (Bit_Chain *restrict dat, Dwg_Color *restrict color,
109106
else if (dxf) \
110107
{ \
111108
char *u8 = bit_convert_TU ((BITCODE_TU)wstr); \
112-
GROUP (dxf); \
109+
dxf_fixup_string (dat, u8, 1, dxf); \
113110
if (u8) \
114-
{ \
115-
dxf_fixup_string (dat, u8, 1, dxf, dxf); \
116-
} \
117-
else \
118-
fprintf (dat->fh, "\r\n"); \
119-
free (u8); \
111+
free (u8); \
120112
} \
121113
}
122114
#define VALUE_TFF(str, dxf) \
123115
{ \
124116
if (dxf) \
125-
{ \
126-
GROUP (dxf); \
127-
dxf_fixup_string (dat, (char *)str, 0, dxf, dxf); \
128-
} \
117+
dxf_fixup_string (dat, (char *)str, 0, dxf); \
129118
}
130119
#define VALUE_BINARY(value, size, dxf) \
131120
{ \
@@ -1240,64 +1229,65 @@ cquote (char *restrict dest, const size_t len, const char *restrict src)
12401229
/* If opts 1:
12411230
quote \n => ^J
12421231
\M+xxxxx => \U+XXXX (shift-jis)
1243-
Splits overlong (len>255) lines into dxf 3 chunks with group 1
1232+
Splits overlong (len>255) lines into dxf 3 chunks ending with group dxf
1233+
only TFF sets opts=0, TV and TU to 1.
12441234
*/
12451235
static void
12461236
dxf_fixup_string (Bit_Chain *restrict dat, char *restrict str, const int opts,
1247-
const int dxf, const int dxfcont)
1237+
const int dxf)
12481238
{
12491239
if (str && *str)
12501240
{
12511241
if (opts
12521242
&& (strchr (str, '\n') || strchr (str, '\r')
12531243
|| strstr (str, "\\M+1")))
12541244
{
1255-
static char _buf[1024] = { 0 };
1245+
static char *cbuf;
1246+
static char _sbuf[1024] = { 0 };
12561247
const size_t origlen = strlen (str);
12571248
long len = (long)((2 * origlen) + 1);
1258-
if (len > 1024)
1259-
{ // FIXME: maybe we need this for chunked strings
1260-
fprintf (dat->fh, "\r\n");
1261-
LOG_ERROR ("Overlarge DXF string, len=%" PRIuSIZE, origlen);
1249+
bool need_free = false;
1250+
if (len < 0)
1251+
{
1252+
LOG_ERROR ("Overlong DXF string");
12621253
return;
12631254
}
1264-
*_buf = '\0';
1265-
len = (long)strlen (cquote (_buf, len, str));
1266-
if (len > 255 && dxf == 1)
1255+
if (len > 1024)
12671256
{
1268-
char *bufp = &_buf[0];
1269-
// GROUP 1 already printed
1270-
while (len > 0)
1257+
cbuf = malloc (len);
1258+
if (!cbuf)
12711259
{
1272-
int rlen = len > 255 ? 255 : len;
1273-
fprintf (dat->fh, "%.*s\r\n", rlen, bufp);
1274-
len -= 255;
1275-
bufp += 255;
1276-
if (len > 0)
1277-
fprintf (dat->fh, "%3d\r\n", dxfcont);
1260+
LOG_ERROR ("Out of memory");
1261+
return;
12781262
}
1263+
*cbuf = '\0';
1264+
need_free = true;
12791265
}
12801266
else
1281-
fprintf (dat->fh, "%s\r\n", _buf);
1267+
cbuf = &_sbuf[0];
1268+
{
1269+
len = (long)strlen (cquote (cbuf, len, str));
1270+
while (len > 0)
1271+
{
1272+
fprintf (dat->fh, "%3d\r\n", len < 250 ? dxf : 3);
1273+
fprintf (dat->fh, "%.*s\r\n", len > 250 ? 250 : (int)len, cbuf);
1274+
len -= 250;
1275+
cbuf += 250;
1276+
}
1277+
}
1278+
if (need_free)
1279+
free (cbuf);
12821280
}
1283-
else
1281+
else // TFF
12841282
{
12851283
long len = (long)strlen (str);
1286-
if (len > 255 && dxf == 1)
1284+
while (len > 0)
12871285
{
1288-
// GROUP 1 already printed
1289-
while (len > 0)
1290-
{
1291-
int rlen = len > 255 ? 255 : len;
1292-
fprintf (dat->fh, "%.*s\r\n", (int)rlen, str);
1293-
len -= 255;
1294-
str += 255;
1295-
if (len > 255)
1296-
fprintf (dat->fh, " 3\r\n");
1297-
}
1286+
fprintf (dat->fh, "%3d\r\n", len < 250 ? dxf : 3);
1287+
fprintf (dat->fh, "%.*s\r\n", len > 250 ? 250 : (int)len, str);
1288+
len -= 250;
1289+
str += 250;
12981290
}
1299-
else
1300-
fprintf (dat->fh, "%s\r\n", str);
13011291
}
13021292
}
13031293
else

0 commit comments

Comments
 (0)