Re: A bug in MetaPost

Andreas Scherer <[email protected]> Tue, 1 Jul 2025 19:46:02 +0200
Newsgroups gmane.comp.tex.metapost
Message-ID <[email protected]>
This is a multi-part message in MIME format.
--------------jy4o0g7vY8YtyQ4fQA0oujn8
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit

 > I found a bug in MetaPost. In source/texk/web2c/mplibdir/mpxout.w, on
 > line 581, there is a single unescaped '%' that is fed to fprintf as
 > the format string in line 645. This is UB by the C standard.

In fact, there are two single unescaped '%'. They appear to be intended 
as TeX comment markers in '\gdef\mpxshipout{...}' and they should---just 
as '\\'---be doubled '%%' for the sake of the C compiler.

The first '%' is redundant after '\bgroup', the second protects against 
spurious whitespace ('\n') after the closing curly brace. A similar '%%' 
should be added after '\\gdef\\stopmpxshipout{...}' in the same static 
string.

Attached is a git-generated diff file that fixes these issues. It also 
makes MPXOUT.W formatting nicely with CWEAVE and pdfTeX. (Correctly 
distinguishing between type 'stat' in boldface and function 'stat' in 
italic is left for the interested reader as an exercise.)

Cheers,
Andreas
--------------jy4o0g7vY8YtyQ4fQA0oujn8
Content-Type: text/x-patch; charset=UTF-8; name="mpxout.diff"
Content-Disposition: attachment; filename="mpxout.diff"
Content-Transfer-Encoding: base64

ZGlmZiAtLWdpdCBhL21weG91dC53IGIvbXB4b3V0LncKaW5kZXggMTU5MTdjZi4uNzUzNGNm
NyAxMDA2NDQKLS0tIGEvbXB4b3V0LncKKysrIGIvbXB4b3V0LncKQEAgLTEwLDExICsxMCwx
NyBAQAogCiBcZGVmXCgjMSl7fSAlIHRoaXMgaXMgdXNlZCB0byBtYWtlIHNlY3Rpb24gbmFt
ZXMgc29ydCB0aGVtc2VsdmVzIGJldHRlcgogXGRlZlw5IzF7fSAlIHRoaXMgaXMgdXNlZCBm
b3Igc29ydCBrZXlzIGluIHRoZSBpbmRleAotXGRlZlxbIzFdeyMxLn0KKworQHMgYXZsX3Ry
ZWUgaW50CitAcyBib29sZWFuIGludAorQHMgZGlyZW50IGludAorQHMgX2ZpbmRkYXRhX3Qg
aW50CitAcyBpbnRwdHJfdCBpbnQKK0BzIHBpZF90IGludAogCiBccGRmb3V0cHV0PTEKIAot
QCogXFsxXSBNYWtlbXB4IG92ZXJ2aWV3LgorQCoqICBNYWtlbXB4IG92ZXJ2aWV3LgogCiBU
aGlzIHNvdXJjZSBmaWxlIGltcGxlbWVudHMgdGhlIG1ha2VtcHggZnVuY3Rpb25hbGl0eSBm
b3IgdGhlIG5ldyBcTVAuCiBJdCBpbmNsdWRlcyBhbGwgb2YgdGhlIGZ1bmN0aW9uYWwgY29k
ZSBmcm9tIHRoZSBvbGQgc3RhbmRhbG9uZSBwcm9ncmFtcwpAQCAtNDAsMTAgKzQ2LDkgQEAg
aW4gb3JkZXIgdG8gcHJldmVudCBuYW1lIGNsYXNoZXMuCiAjaW5jbHVkZSA8c3RkYXJnLmg+
CiAjaW5jbHVkZSA8YXNzZXJ0Lmg+CiAjaW5jbHVkZSA8c2V0am1wLmg+Ci0jaW5jbHVkZSA8
ZXJybm8uaD4gLyogVE9ETyBhdXRvY29uZiA/ICovCi0vKiB1bmlzdGQuaCBpcyBuZWVkZWQg
Zm9yIGV2ZXJ5IG5vbi1XaW4zMiBwbGF0Zm9ybSwgYW5kIHdlIGFzc3VtZQotICogdGhhdCBp
bXBsaWVzIHRoYXQgc3lzL3R5cGVzLmggaXMgYWxzbyBwcmVzZW50IAotICovCisjaW5jbHVk
ZSA8ZXJybm8uaD4gLyogVE9ETyBhdXRvY29uZiA/ICovIEB0QD4KKy8qIHVuaXN0ZC5oIGlz
IG5lZWRlZCBmb3IgZXZlcnkgbm9uLVdpbjMyIHBsYXRmb3JtLCBhbmQgd2UgYXNzdW1lICov
IEB0QD4KKy8qIHRoYXQgaW1wbGllcyB0aGF0IHN5cy90eXBlcy5oIGlzIGFsc28gcHJlc2Vu
dCAqLwogI2lmbmRlZiBXSU4zMgogI2luY2x1ZGUgPHN5cy90eXBlcy5oPgogI2luY2x1ZGUg
PHVuaXN0ZC5oPgpAQCAtMTExLDggKzExNiw4IEBAIFRoZSBtb3JlIGNvbXBsZXggZGF0YXR5
cGVzIGFyZSBkZWZpbmVkIGluIHRoZSBmb2xsb3dpbmcgc2VjdGlvbnMuCiBAYwogdHlwZWRl
ZiBzaWduZWQgaW50IHdlYl9pbnRlZ2VyOwogdHlwZWRlZiBzaWduZWQgaW50IHdlYl9ib29s
ZWFuOwotQDxDIERhdGEgVHlwZXNAPgotQDxEZWNsYXJhdGlvbnNAPgorQDxDIERhdGEgVHlw
ZXNAPkA7CitAPERlY2xhcmF0aW9uc0A+QDsKIAogQCBUaGUgc2luZ2xlIG1vc3QgaW1wb3J0
YW50IGRhdGEgc3RydWN0dXJlIGlzIHRoZSBzdHJ1Y3R1cmUKIHxtcHhfZGF0YXwuICBJdCBj
b250YWlucyBhbGwgb2YgdGhlIGdsb2JhbCBzdGF0ZSBmb3IgYSBzcGVjaWZpYwpAQCAtMTMx
LDcgKzEzNiw3IEBAIHR5cGVkZWYgZW51bSB7CiAgIG1weF90cm9mZl9tb2RlPTEgCiB9IG1w
eF9tb2RlczsKIHR5cGVkZWYgc3RydWN0IG1weF9kYXRhICogTVBYOwotQDxNYWtlbXB4IGhl
YWRlciBpbmZvcm1hdGlvbkA+CitAPE1ha2VtcHggaGVhZGVyIGluZm9ybWF0aW9uQD5AOwog
I2VuZGlmCiAKIEAgQDxDIERhdGEgVHlwZXNAPj0KQEAgLTI4NCw3ICsyODksNyBAQCBzdGF0
aWMgdm9pZCBtcHhfZmNsb3NlIChNUFggbXB4LCBGSUxFICpmaWxlKSB7CiB9CiAKIEAgCi1A
ZCB4ZnJlZShBKSBkbyB7IG1weF94ZnJlZShBKTsgQT1OVUxMOyB9IHdoaWxlICgwKQorQGQg
eGZyZWUoQSkgZG8geyBtcHhfeGZyZWUoQSk7IEE9TlVMTDsgfSB3aGlsZSAoMClAOwogQGQg
eHJlYWxsb2MoUCxBLEIpIG1weF94cmVhbGxvYyhtcHgsUCxBLEIpCiBAZCB4bWFsbG9jKEEs
QikgIG1weF94bWFsbG9jKG1weCxBLEIpCiBAZCB4c3RyZHVwKEEpICBtcHhfeHN0cmR1cCht
cHgsQSkKQEAgLTU3NywxNyArNTgyLDE3IEBAIHN0YXRpYyB2b2lkIG1weF9jb3B5X21wdG8g
KE1QWCBtcHgsIEZJTEUgKm91dGZpbGUsIGludCB0ZXh0eXBlKSB7CiBzdGF0aWMgY29uc3Qg
Y2hhciAqbXB4X3ByZWRvY1tdICA9IHsiIiwgIi5wbyAwXG4ifTsKIHN0YXRpYyBjb25zdCBj
aGFyICptcHhfcG9zdGRvY1tdID0geyAiXFxlbmR7ZG9jdW1lbnR9XG4iLCAiIn07CiBzdGF0
aWMgY29uc3QgY2hhciAqbXB4X3ByZXRleDFbXSA9IHsgCi0gICAgIlxcZ2RlZlxcbXB4c2hp
cG91dHtcXHNoaXBvdXRcXGhib3hcXGJncm91cCVcbiIKLSAgICAiICBcXHNldGJveDA9XFxo
Ym94XFxiZ3JvdXB9JVxuIgotICAgICJcXGdkZWZcXHN0b3BtcHhzaGlwb3V0e1xcZWdyb3Vw
IgotICAgICIgIFxcZGltZW4wPVxcaHQwIFxcYWR2YW5jZVxcZGltZW4wXFxkcDBcbiIKLSAg
ICAiICBcXGRpbWVuMT1cXGh0MCBcXGRpbWVuMj1cXGRwMFxuIgotICAgICIgIFxcc2V0Ym94
MD1cXGhib3hcXGJncm91cFxuIgotICAgICIgICAgXFxib3gwXG4iCi0gICAgIiAgICBcXGlm
bnVtXFxkaW1lbjA+MCBcXHZydWxlIHdpZHRoMXNwIGhlaWdodFxcZGltZW4xIGRlcHRoXFxk
aW1lbjIgXG4iCi0gICAgIiAgICBcXGVsc2UgXFx2cnVsZSB3aWR0aDFzcCBoZWlnaHQxc3Ag
ZGVwdGgwc3BcXHJlbGF4XG4iCi0gICAgIiAgICBcXGZpXFxlZ3JvdXBcbiIKLSAgICAiICBc
XGh0MD0wcHQgXFxkcDA9MHB0IFxcYm94MCBcXGVncm91cH1cbiIKKyAgICAiXFxnZGVmXFxt
cHhzaGlwb3V0e1xcc2hpcG91dFxcaGJveFxcYmdyb3VwXG4iIEB8CisgICAgIiAgXFxzZXRi
b3gwPVxcaGJveFxcYmdyb3VwfSUlXG4iIEB8CisgICAgIlxcZ2RlZlxcc3RvcG1weHNoaXBv
dXR7XFxlZ3JvdXAiIEB8CisgICAgIiAgXFxkaW1lbjA9XFxodDAgXFxhZHZhbmNlXFxkaW1l
bjBcXGRwMFxuIiBAfAorICAgICIgIFxcZGltZW4xPVxcaHQwIFxcZGltZW4yPVxcZHAwXG4i
IEB8CisgICAgIiAgXFxzZXRib3gwPVxcaGJveFxcYmdyb3VwXG4iIEB8CisgICAgIiAgICBc
XGJveDBcbiIgQHwKKyAgICAiICAgIFxcaWZudW1cXGRpbWVuMD4wIFxcdnJ1bGUgd2lkdGgx
c3AgaGVpZ2h0XFxkaW1lbjEgZGVwdGhcXGRpbWVuMiBcbiIgQHwKKyAgICAiICAgIFxcZWxz
ZSBcXHZydWxlIHdpZHRoMXNwIGhlaWdodDFzcCBkZXB0aDBzcFxccmVsYXhcbiIgQHwKKyAg
ICAiICAgIFxcZmlcXGVncm91cFxuIiBAfAorICAgICIgIFxcaHQwPTBwdCBcXGRwMD0wcHQg
XFxib3gwIFxcZWdyb3VwfSUlXG4iIEB8CiAgICAgIlxcbXB4c2hpcG91dCUlIGxpbmUgJWQg
JXNcbiIsICIubGYgJWQgJXNcbiIgfTsKIHN0YXRpYyBjb25zdCBjaGFyICptcHhfcHJldGV4
W10gPSB7ICJcXG1weHNoaXBvdXQlJSBsaW5lICVkICVzXG4iLCAiLmJwXG4ubGYgJWQgJXNc
biIgfTsKIHN0YXRpYyBjb25zdCBjaGFyICptcHhfcG9zdHRleFtdID0geyAiXG5cXHN0b3Bt
cHhzaGlwb3V0XG4iLCAiXG4iIH07CkBAIC0xMzk2LDcgKzE0MDEsNyBAQCB3b3J0aHdoaWxl
IHRvIHNsaWRlIGV2ZXJ5dGhpbmcgZG93biBqdXN0IHRvIHNhdmUgYSBsaXR0bGUgc3BhY2Uu
CiAKIEA8RmluaXNoIHNldHRpbmcgdXAgdGhlIGRhdGEgc3RydWN0dXJlcyBmb3IgdGhlIG5l
dyB2aXJ0dWFsIGZvbnRAPj0KIG1weC0+ZmJhc2VbZl09KHdlYl9pbnRlZ2VyKShtcHgtPnZm
X3B0cisxKTsKLW1weC0+aW5mb19wdHI9KHVuc2lnbmVkIGludCkobXB4LT5pbmZvX2Jhc2Vb
Zl0rbXB4LT5mb250X2VjW2ZdKzEpCittcHgtPmluZm9fcHRyPSh1bnNpZ25lZCBpbnQpKG1w
eC0+aW5mb19iYXNlW2ZdK21weC0+Zm9udF9lY1tmXSsxKUA7CiAKIAogQCogTG9hZGluZyBm
b250cy4KQEAgLTIzMDMsNyArMjMwOCw3IEBAIHN0YXRpYyB2b2lkIG1weF9kb194eHggKE1Q
WCBtcHgsIHdlYl9pbnRlZ2VyIHApCiAgICAgYnVmW2xlbl0gPSAodW5zaWduZWQgY2hhcilt
cHhfZ2V0X2J5dGUobXB4KTsKICAgICBkZWNyKHApOyBpbmNyKGxlbik7CiAgIH0KLSAgQDxD
aGVjayB3aGV0aGVyIHxidWZ8IGNvbnRhaW5zIGEgY29sb3IgY29tbWFuZDsgaWYgbm90LCB8
Z290byBYWFhYfEA+CisgIEA8Q2hlY2sgd2hldGhlciB8YnVmfCBjb250YWlucyBhIGNvbG9y
IGNvbW1hbmQ7IGlmIG5vdCwgfGdvdG8gWFhYWHxAPkA7CiAgIGlmICggcCA+IDAgKSB7CiAg
ICAgIGNvbG9yX3dhcm4oImxvbmcgXCJjb2xvclwiIHNwZWNpYWwgaWdub3JlZCIpOyAKICAg
ICAgZ290byBYWFhYOyAKQEAgLTI0MDcsNyArMjQxMiw3IEBAIHdoaWxlICggKGwgPCBsZW4p
ICYmIChidWZbbF0gPT0gJyAnKSApIGluY3IobCk7IC8qICBSZW1vdmUgc3BhY2VzIGF0IGVu
ZCBvZiBidWYKIHdoaWxlICggKGxlbiA+IGwpICYmIChidWZbbGVuIC0gMV0gPT0gJyAnKSAp
IGRlY3IobGVuKTsKIG1weC0+Y29sb3Jfc3RhY2tbbXB4LT5jb2xvcl9zdGFja19kZXB0aF09
eG1hbGxvYygoc2l6ZV90KShsZW4tbCszKSwxKTsKIGsgPSAwOwotQDxDb3B5IHxidWZbbF18
IHRvIHxjb2xvcl9zdGFja1tjb2xvcl9zdGFja19kZXB0aF1ba118IGluIHR1cGxlIGZvcm1A
PgorQDxDb3B5IHxidWZbbF18IHRvIHxjb2xvcl9zdGFja1tjb2xvcl9zdGFja19kZXB0aF1b
a118IGluIHR1cGxlIGZvcm1APkA7CiAKIEAgQDx8YnVmW2xdfCBjb250YWlucyBhIGdyYXkg
Y29tbWFuZEA+PQogKGwgKyA1IDwgbGVuKQpAQCAtMjQyNCw3ICsyNDI5LDcgQEAgd2hpbGUg
KCAobGVuID4gbCkgJiYgKGJ1ZltsZW4gLSAxXSA9PSAnICcpICkgZGVjcihsZW4pOwogbXB4
LT5jb2xvcl9zdGFja1ttcHgtPmNvbG9yX3N0YWNrX2RlcHRoXT14bWFsbG9jKChzaXplX3Qp
KGxlbi1sKzkpLDEpOwogc3RyY3B5KG1weC0+Y29sb3Jfc3RhY2tbbXB4LT5jb2xvcl9zdGFj
a19kZXB0aF0sIndoaXRlKiIpOwogayA9IDY7Ci1APENvcHkgfGJ1ZltsXXwgdG8gfGNvbG9y
X3N0YWNrW2NvbG9yX3N0YWNrX2RlcHRoXVtrXXwgaW4gdHVwbGUgZm9ybUA+CitAPENvcHkg
fGJ1ZltsXXwgdG8gfGNvbG9yX3N0YWNrW2NvbG9yX3N0YWNrX2RlcHRoXVtrXXwgaW4gdHVw
bGUgZm9ybUA+QDsKIAogQCBAPHxidWZbbF18IGNvbnRhaW5zIGEgY215ayBjb21tYW5kQD49
CiAobCArIDUgPCBsZW4pCkBAIC0yNDQyLDcgKzI0NDcsNyBAQCB3aGlsZSAoIChsZW4gPiBs
KSAmJiAoYnVmW2xlbiAtIDFdID09ICcgJykgKSBkZWNyKGxlbik7CiBtcHgtPmNvbG9yX3N0
YWNrW21weC0+Y29sb3Jfc3RhY2tfZGVwdGhdPXhtYWxsb2MoKHNpemVfdCkobGVuLWwrNyks
MSk7CiBzdHJjcHkobXB4LT5jb2xvcl9zdGFja1ttcHgtPmNvbG9yX3N0YWNrX2RlcHRoXSwi
Y215ayIpOwogayA9IDQ7Ci1APENvcHkgfGJ1ZltsXXwgdG8gfGNvbG9yX3N0YWNrW2NvbG9y
X3N0YWNrX2RlcHRoXVtrXXwgaW4gdHVwbGUgZm9ybUA+CitAPENvcHkgfGJ1ZltsXXwgdG8g
fGNvbG9yX3N0YWNrW2NvbG9yX3N0YWNrX2RlcHRoXVtrXXwgaW4gdHVwbGUgZm9ybUA+QDsK
IAogQCBAPENvcHkgfGJ1ZltsXXwgdG8gfGNvbG9yX3N0YWNrW2NvbG9yX3N0YWNrX2RlcHRo
XVtrXXwgaW4gdHVwbGUgZm9ybUA+PQogbXB4LT5jb2xvcl9zdGFja1ttcHgtPmNvbG9yX3N0
YWNrX2RlcHRoXVtrXSA9ICcoJzsKQEAgLTI0OTcsNyArMjUwMiw3IEBAIGlmICggbXB4LT5j
b2xvcl9zdGFja19kZXB0aCA+IDAgKSB7CiB9CiAKIAotQCogXFs0XSBEbXAuCitAKiogRG1w
LgogCiBUaGlzIHByb2dyYW0gcmVhZHMgZGV2aWNlLWluZGVwZW5kZW50IHRyb2ZmIG91dHB1
dCBmaWxlcywKIGFuZCBjb252ZXJ0cyB0aGVtIGludG8gYSBzeW1ib2xpYyBmb3JtIHVuZGVy
c3Rvb2QgYnkgTWV0YVBvc3QuICBTb21lCkBAIC0zMTM3LDcgKzMxNDIsNyBAQCBJdCBpcyBh
IGhhY2ssIEkga25vdy4gSSd2ZSBzdHVjayB0byAgbmFtZXMgb24gVGVYTGl2ZS4KIEBkIHRl
c3RfcmVkb19zZWFyY2ggZG8gewogICAgaWYgKGRlZmY9PU5VTEwpCiAJIGRlZmYgPSBtcHhf
ZnNlYXJjaChtcHgsIGNuYW1lLCBtcHhfc3BlY2NoYXJfZm9ybWF0KTsKLSB9IHdoaWxlICgw
KQorIH0gd2hpbGUgKDApIEA7CiAKIEBjCiBzdGF0aWMgY2hhciAqbXB4X2NvcHlfc3BlY19j
aGFyKE1QWCBtcHgsIGNoYXIgKmNuYW1lKSB7CkBAIC0zNzgzLDcgKzM3ODgsNyBAQCBzdGF0
aWMgaW50IG1weF9kbXAoTVBYIG1weCwgY2hhciAqaW5maWxlKSB7CiB9CiAKIAotQCogXFs1
XSBNYWtlbXB4LgorQCoqIE1ha2VtcHguCiAKIAogTWFrZSBhbiBNUFggZmlsZSBmcm9tIHRo
ZSBsYWJlbHMgaW4gYSBNZXRhUG9zdCBzb3VyY2UgZmlsZSwKQEAgLTQwMjUsNyArNDAzMCw3
IEBAIHN0YXRpYyBpbnQgbXB4X3J1bl9jb21tYW5kKE1QWCBtcHgsIGNoYXIgKmlubmFtZSwg
Y2hhciAqb3V0bmFtZSwgaW50IGNvdW50LCBjaGFyCiAgICAgcmV0dXJuIHJldGNvZGU7CiB9
CiAKLUAgQCBSdW5uaW5nIFRyb2ZmIGlzIG1vcmUgbGlrZWx5IHRoYW4gbm90IGEgc2VyaWVz
IG9mIHBpcGVzIHRoYXQgCitAIFJ1bm5pbmcgVHJvZmYgaXMgbW9yZSBsaWtlbHkgdGhhbiBu
b3QgYSBzZXJpZXMgb2YgcGlwZXMgdGhhdAogZmVlZCBpbnB1dCB0byBlYWNoIG90aGVyLiBN
YWtlbXB4IGRvZXMgYWxsIG9mIHRoaXMgaXRzZWxmIGJ5IHVzaW5nCiB0ZW1wb3JhcnkgZmls
ZXMgaW5iZXR3ZWVuLiBUaGF0IG1lYW5zIHdlIGhhdmUgdG8ganVnZ2xlIGFib3V0IHdpdGgK
IHxzdGRpbnwgYW5kIHxzdGRvdXR8LgpAQCAtNDM4MCwzICs0Mzg1LDUgQEAgaWYgKG1weF9u
ZXdlcihtcHhvcHQtPm1wbmFtZSwgbXB4b3B0LT5tcHhuYW1lKSkKICNlbmRpZgogI2VuZGlm
CiBAPSAvKkBAK2J1ZmZlcm92ZXJmbG93aGlnaEBAKi8gQD4gCisKK0AqIEluZGV4Lgo=

--------------jy4o0g7vY8YtyQ4fQA0oujn8
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

--
http://tug.org/metapost/

--------------jy4o0g7vY8YtyQ4fQA0oujn8--