Skip to content

Commit b0c3c5f

Browse files
committed
pp_pack.c: S_utf8_to_bytes: Rmv loop
Prior to this commit, the code went through the buffer with warnings turned off, but saving the fact if there were problems. If so, it ran through the buffer again, with warnings turned on to display those problems. I'm unsure of why it didn't output any warnings until it got to the end. But utf8_to_uv_msgs() allows us to store up the messages and output them later in the same order as encountered, and without having to reparse
1 parent f087bac commit b0c3c5f

File tree

1 file changed

+36
-15
lines changed

1 file changed

+36
-15
lines changed

pp_pack.c

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -288,46 +288,67 @@ S_utf8_to_bytes(pTHX_ const char **s, const char *end, const char *buf, SSize_t
288288
if (UNLIKELY(needs_swap))
289289
buf += buf_len;
290290

291+
AV * msgs = NULL;
291292
for (; buf_len > 0; buf_len--) {
292293
if (from >= end) return FALSE;
293-
if (! utf8_to_uv_flags((U8 *) from, (U8 *) end, &val, &retlen, flags))
294-
{
295-
bad |= 1;
296-
}
297294

295+
AV * this_msgs = NULL;
296+
if (utf8_to_uv_msgs((U8 *) from, (U8 *) end, &val, &retlen, flags,
297+
NULL, &this_msgs))
298+
{
298299
if (val >= 0x100) {
299300
bad |= 2;
300301
val = (U8) val;
301302
}
303+
}
302304

303305
from += retlen;
304306

307+
/* Add any messages from this conversion to the list for later output
308+
* */
309+
if (this_msgs) {
310+
while (av_count(this_msgs) > 0) {
311+
av_push(msgs, av_shift(this_msgs));
312+
}
313+
314+
Safefree(this_msgs);
315+
}
316+
305317
if (UNLIKELY(needs_swap))
306318
*(U8 *)--buf = (U8)val;
307319
else
308320
*(U8 *)buf++ = (U8)val;
309321
}
310322

311323
/* We have enough characters for the buffer. Did we have problems ? */
312-
if (bad) {
313-
if (bad & 1) {
314-
/* Rewalk the string fragment while warning */
315-
const char *ptr;
316-
const U32 flags = ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY;
317-
for (ptr = *s; ptr < from; ptr += UTF8SKIP(ptr)) {
318-
if (ptr >= end) break;
319-
utf8n_to_uvchr((U8 *) ptr, end-ptr, &retlen, flags);
320-
}
321-
if (from > end) from = end;
324+
if (msgs) {
325+
while (av_count(msgs) > 0) {
326+
HV * msg_hash = (HV *) av_shift(msgs);
327+
SV ** packed_categories_p = hv_fetchs(msg_hash, "warn_categories", 0);
328+
if (packed_categories_p == NULL) {
329+
continue;
330+
}
331+
332+
UV packed_categories = SvUV(*packed_categories_p);
333+
if (packed_categories == 0) {
334+
continue;
335+
}
336+
337+
SV ** warn_text_p = hv_fetchs(msg_hash, "text", 0);
338+
if (warn_text_p) {
339+
warner(packed_categories, "%s", SvPV_nolen(*warn_text_p));
340+
}
322341
}
323342

343+
Safefree(msgs);
344+
}
345+
324346
if ((bad & 2))
325347
ck_warner(packWARN(datumtype & TYPE_IS_PACK ?
326348
WARN_PACK : WARN_UNPACK),
327349
"Character(s) in '%c' format wrapped in %s",
328350
(int) TYPE_NO_MODIFIERS(datumtype),
329351
datumtype & TYPE_IS_PACK ? "pack" : "unpack");
330-
}
331352

332353
*s = from;
333354
return TRUE;

0 commit comments

Comments
 (0)