From 5040280e384c99f4eb2971889d68d0355ed8717a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andreas=20H=C3=BCttel?= Date: Sat, 7 Feb 2015 17:47:17 +0000 Subject: [PATCH] Backport patch for CVE-2014-9654, bug 539108. Unfortunately this does bad things to a header file, so forcing a rebuild by mangling subslots... Package-Manager: portage-2.2.15/cvs/Linux x86_64 Manifest-Sign-Key: 0x84AD142F --- dev-libs/icu/ChangeLog | 11 +- dev-libs/icu/Manifest | 34 +- .../icu/files/icu-54.1-CVE-2014-9654.patch | 1105 +++++++++++++++++ ...{icu-53.1-r1.ebuild => icu-53.1-r3.ebuild} | 6 +- dev-libs/icu/icu-54.1-r1.ebuild | 134 ++ 5 files changed, 1270 insertions(+), 20 deletions(-) create mode 100644 dev-libs/icu/files/icu-54.1-CVE-2014-9654.patch rename dev-libs/icu/{icu-53.1-r1.ebuild => icu-53.1-r3.ebuild} (94%) create mode 100644 dev-libs/icu/icu-54.1-r1.ebuild diff --git a/dev-libs/icu/ChangeLog b/dev-libs/icu/ChangeLog index 4dd487cea1ac..b03844e4a668 100644 --- a/dev-libs/icu/ChangeLog +++ b/dev-libs/icu/ChangeLog @@ -1,6 +1,15 @@ # ChangeLog for dev-libs/icu # Copyright 1999-2015 Gentoo Foundation; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/dev-libs/icu/ChangeLog,v 1.292 2015/02/01 17:00:52 mgorny Exp $ +# $Header: /var/cvsroot/gentoo-x86/dev-libs/icu/ChangeLog,v 1.293 2015/02/07 17:47:06 dilfridge Exp $ + +*icu-54.1-r1 (07 Feb 2015) +*icu-53.1-r3 (07 Feb 2015) + + 07 Feb 2015; Andreas K. Huettel -icu-53.1-r1.ebuild, + +icu-53.1-r3.ebuild, +icu-54.1-r1.ebuild, + +files/icu-54.1-CVE-2014-9654.patch: + Backport patch for CVE-2014-9654, bug 539108. Unfortunately this does bad + things to a header file, so forcing a rebuild by mangling subslots... *icu-54.1 (01 Feb 2015) diff --git a/dev-libs/icu/Manifest b/dev-libs/icu/Manifest index 1e3c61cc904f..6be405a01714 100644 --- a/dev-libs/icu/Manifest +++ b/dev-libs/icu/Manifest @@ -1,34 +1,34 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 +AUX icu-54.1-CVE-2014-9654.patch 48898 SHA256 8645e8093be50682a75730a47b30b96ab65cbf28f9934c7d791fb92d0fca58ef SHA512 6f13fc740cbc718db24ee2ea6f94e78a990d2bc136c096f6db0c06ae27438516c414a32abcdedbf328d3c51871c86dd73e713955bc11197d8ffea20f4fe651d0 WHIRLPOOL 505eb5e33582d8034bef5a8d85901bbf34d02531b1a2a2fede11d4e3f91a4b14fb4ca5e14ebec00a1b49a1c64f7e9c5aec3799af6072c45fc0e0f5c436e7bf05 AUX icu-fix-tests-depending-on-date.patch 558 SHA256 1c9891d7d3ad4e498e46bf4cece5d98ea9128678a3e5c26b306d0ac600ffcbe0 SHA512 f5e6dde3c6850682a9b66ad2929fc4137b7fc9101a979e5eecb6e0fc60afacd0e3b4fcc96f91dcf558f41f17a0647a0fd167839f9c116149cce0c356f8ced633 WHIRLPOOL f732bb97764b1384025a3b98f0f1fbd05165cdec02fd448b9626c7aaa2f5d9ba07b2e2057a569f4ce2e947f4d8867265956818fef1a5373931de54ec5fc99d13 AUX icu-remove-bashisms.patch 5982 SHA256 432e49d3e75465324e80db29f27f4d8864d12ba644878d5287e7a942e3671858 SHA512 a984aba10d7fb92e8d7cb0d9c5d8c0c2193a817ce05113168110a89adf7df754dc82dbe8d134ea5c8d44650badaebd5f60303232d7f2a8e246144dc70639f049 WHIRLPOOL 80df1f9c572f6b4d99c73809d839117a7a3849968f67ac5f58928d2fa44974ccad17c6eb95e5ce880002f72cc0131cf2f7664f66e53a1b2fde541b2b6f943015 DIST icu4c-52_1-src.tgz 23875368 SHA256 2f4d5e68d4698e87759dbdc1a586d053d96935787f79961d192c477b029d8092 SHA512 5300b1d97340850d3d72af220ff5cbc2ae2820aff4367b60e52f17ead9831011dcda3d4c5af57c899d47b6fc964b23c9c8922954b32d314d669eb1a479a2efb0 WHIRLPOOL fd9d0ed8f55b93349164595c79544f41791774eff5e82b043be333732104b19c4036f6a6c53784bfe4494c005b950a4e96433646be24f310a681a18db0d19bfd DIST icu4c-53_1-src.tgz 23218952 SHA256 6fa74fb5aac070c23eaba1711a7178fe582c59867484c5ec07c49002787a9a28 SHA512 2172bfa7d61172b62380762f180336cf86264faed247e57f9143a5dcc84c286b96baa100302c0d54fe6f51af2d7e286cc5176db8f99c58157a5a750270e770df WHIRLPOOL 760b0e2315b7e097d296442cb33c7e9d154bd52dee649e8c85f85c6c9cbd96e26843f0b176c9afcb33a47987ffd1ed7355e67c92d5c4cbcf01a222a3f3eabdee DIST icu4c-54_1-src.tgz 25485678 SHA256 d42bc9a8ca6a91c55eb0925c279f49e5b508d51ef26ac9850d9be55de5bb8ab3 SHA512 d54d4cd826e1aef62a574595a04f9fec0a42c4445ed0a166a6bb5c5f3c9f692bf3273756f350233f50b2a1ad32c437dedfeeac96d6dc814d27bfd9159b7a651c WHIRLPOOL 1ae01eb26824ca591ff76ea040f703023f24975ad4177d49b1dd60f7e7f96f60884745d6c6e5e2bdf17fc8e104e97ed814f6c0ca051d1807814e324eb24e94dd EBUILD icu-52.1.ebuild 3129 SHA256 cf990bf7fdecf33dc3d2481acd694c712f9e7356d4f2684c42a73c63bc132ee2 SHA512 009af7ea758a39d29c51924372ccc71b48c380e6c349f20910f1ea140f8642700897f6cb318c6c9cc7faaff052f612e0698c6c3f7bc0728c339d10a8d53144a2 WHIRLPOOL 2723d3ff372373d0733c9c3e5c627db4b461e16d58bead0f8ec9aaf88607fcee80d85d438dd1094ac5239b482fba29319e056a31a369506fb50401e2617653b3 -EBUILD icu-53.1-r1.ebuild 3191 SHA256 1fa7a96e6a6160c2c38c07c3e08cfc55ad6f1e37ef0bd005aacaa7491dd377a5 SHA512 74773f86be2a59562eac1e15c8ebf66097a9d140b760bd5ed107ad7dca84197ae1b17059b6711150054b48f66c9168199742584df42416766c80d4e9fcc18b37 WHIRLPOOL 6283e8f934c1deb1d9c53a01b6406cb975f91886671514f20423ddcfd3a5e5f26add4d0e765b17b64ac0e31d762753fbd2d0bdda21ed96f235d8045d69106dd8 EBUILD icu-53.1-r2.ebuild 3191 SHA256 d85e29ca6ed9b46102fcce531cff7aaa22ebca32540a167a3c166ff8794dd29a SHA512 16b56f39ca48024cf33c65c803c66e3a9aa5a4731c64c9cd45e580fd0e1d14631eb2636c30e21d3c9afa91056cd94f516bb5226841bf6b0d51d1809d3a1edee7 WHIRLPOOL 0813ad4a1c5c78713c5a7a7ba3e19c97b738579f35a5a69da4f5ae589f58d200f38b7dd9dbca67e0252f607fd0a7b94c3b0de3d8ee367986f734cb51384e9ee7 +EBUILD icu-53.1-r3.ebuild 3251 SHA256 52b6c692999547fe6f28d1952465c301a586be4abf03362d3db12a89fe6026de SHA512 f724ff41d43f80af785a88a6d495cf7da0255eb6e57c5fa27670c9a2745676be915e610c507b211182c18910e5f28b339577fd8bd7ce0908f8b3763ce7f93624 WHIRLPOOL 0382ae9c676350199ac331fed391074dd72f53d35a72979b175e8c5f4442373f484d88ce3eb90658a008bcee368ea0b70cf8f665db2259acaf9e89241661753a EBUILD icu-53.1.ebuild 3132 SHA256 4403839fee702aafa7d934ab3824282497d4b659625028637e562c51af1a3eeb SHA512 6fbfdffc515c8a8f30cbc77d15ef385b2f12b82e7c0fc9787273b3a8ce10e0b0789e5f48b98c0ba33c3c844e329ac0cd3b59041c6b8b684da3eed2e950f0c5be WHIRLPOOL 7dba17c0e738f329f7288a2bebdbc297e668b0f248502bea28114acb0d12ef9f7356d9390121fa87f86a4c5d9224b926c66e9f0bdbdd485e6ca60073b6260cbe +EBUILD icu-54.1-r1.ebuild 3037 SHA256 0173854871205c3337eb586ee3abcfcde2ae4a9243c33e86584b92d4a12f4a85 SHA512 58e6361133583b8fb843d7527f954b183fd7189dd5bf9d266679e38f7f4ade3d700ba99318e7ec801b67e88e5e87b96ac711c5e1c279c5e09ba1051186f03064 WHIRLPOOL db121653982a1b8161ce0a8a5067daf75900fe27ea9cda885edd26c481f24e4e418168e7b49cfbed7fa8307fb84b7b644c2be24357743701d8e36c4115813a9e EBUILD icu-54.1.ebuild 2983 SHA256 f9f93ecb7072e3c75123bc57101a4f289fba80313a857b8822191e63b42598c8 SHA512 1b2894c2007ba9a61162c6c4fa66f857a08efef09b1383725412b4e291ae6d8943ded681bee135fba3691bb5c4b2373fdcb8b6fe744bcecc8dae6ed57c91a213 WHIRLPOOL ec50751e4e341a4e67eae7cf209263141727bc0a5e2777e383665fef042aafb7a7501bf58089261f453b053dd9a83b24f06fc77c8991fa509055d71d2d576039 -MISC ChangeLog 38172 SHA256 b8badaf07a6882fe5bcf977ade4e992e777592d92dba02ffb2a8fd429779f64b SHA512 3c1373c416328a08b928c69d8a8c76bef52604b36f9eb71937054fd84b133de58c77874fccd5b1ca95a8714b230132b5f9f34bfc0eb234c68f7651823e179f68 WHIRLPOOL 871a3caa5b590ef190c2a24b74e4c45a6a45df17b78b9d7dfef608aa84ead48ba3b2b594284babbb9ee93a295ff2f5612f9c64f31fea426059c5aa60d78e9e21 +MISC ChangeLog 38540 SHA256 9cb4323106871fb7f270c1415d3ebdc6c91be05212d4de5d3eb10bcec64e50b8 SHA512 a380fc4a3bf1a38c24c428d9e6a61e6608b85d0b4c5707966422907075328a8449017c6c8e1d17df02130f136e9001c591662a92a761fa8acf6191a9fd1c2982 WHIRLPOOL 5c757034fcdae1df64d7ede56fa5ad0b7fe81b5a6912b9319b98066a47aa51d36980894b4a3434662de4c8f7ed59964171a8096e4e76a1f1057eac123255f940 MISC metadata.xml 164 SHA256 6dd077e0a4bddf8cac0a6d7fb01d5f992a81c85d77d55787d19c6d4ae4c5aeeb SHA512 acd8ec5158c34fd738af175dda4c270a884c80e76dd10d9252e2513846ae1cb69ed8b1afe328a69ced10974ca3c60366394990b98a0d9b9815527f262afd9937 WHIRLPOOL 43b43d99d3c96c6da7006df219d57a4ff853353940dbd597bbbd2be00af7b38f0e6c3e33024b1e964ef1fedb12f788ea78693b7e3527011d8bbb9757ec0b88a2 -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 -iQJ8BAEBCABmBQJUzlvKXxSAAAAAAC4AKGlzc3Vlci1mcHJAbm90YXRpb25zLm9w -ZW5wZ3AuZmlmdGhob3JzZW1hbi5uZXQ2REJCMDdDQzRGMERBRDA2RUEwQUZFNDFC -MDdBMUFFQUVGQjQ0NjRFAAoJELB6GurvtEZOPzIQAIFfTYKSNQrFMEM+HOxjHiFe -TFhMlOVDIKjoxUqnPAHnglIEm+3vW1h/PYLWc73H5wEvG4Vgq6hv+HIJj97fAhzq -7ukxcRPH8hqtzzMq7xjKBltsH9HCrlufUo3cLe08+Wqa43kRd3UDpfU+FC4wdZfp -+arj15mlLx4uG2qYA67Es0tWiGjNIvELo09/o6DgujUe4l8YOtyrv04RzLXa7AEp -LLkjd2U2W7aQuIszaaOn7Zk3s2OA4EMyxhB7LeDkASqs3NcAhFiC5zxiut+t+0H1 -I7nqNyDr50PtmIgZOmiuVMX4gf49I+MbmORN8/SAbzoGjLK228OucWfoamgPeZL+ -CkFNvDdXEaP/hp/ZpDwJLnkJ4gduwgS14BZ0CqgsqNMqmQLgxlHcuSjMRN0Qe+0g -QOWzCzyhWKzYyeXEE5LKdk2jrKiM/1x4n3C4XVVHaQFPFE987lZ2ky2+JNcpvxSa -lHzxZWol0+gu/2wKAY5fYZ98SWv7M3H+FAySo3K/UI+/w0it6BDFq0zTxBZCL/05 -u1LkZvrGoKp6YZoTX3Y9oipe79EoVaI8sa88a6grhyssTxfIHsF3FnQINpqzYSp2 -Xwf8wLiOLnC/zfgxKvqDSfk2utblj2PfT5UmBZRhVeQDxbDP1fwt6fX8mQ03bkIc -y3MjGy1dEDsXCJx1mnT7 -=gOeI +iQIcBAEBCAAGBQJU1lAbAAoJEB9VdM6hupKVdUwQAIM2x9dXfvAZ+7Jsl3nMma2e +6CGtQhR8O4mm/ddFmQB85s/VduBRkaglJ18ZMBG5DaXb8jO5EL2ZEAn/TK9PUmKi +/G4Zz6j2jK6RKz8nRzDce2SLjVxYQfEdlWQF7Ciu4f3Q4WcUefI8kPqt7pEttbCJ +b2pOnVDKopS94YJ5+gsQg6zv9wU0t+REmzuFD5WIJI2IvShFD87wQweo2P8KwcPj +2sfmtbAdEo38TSPOUGBxIm/KdIyiG4Mr64NwbgiCbi0sI+7vctzJlFiCvljB/4zz +abzg+qhy4wk4x33IHQWgVzEf+wkPEeucdp906JUghVODVNZR3LcgcLgjRpQ2EvYA +VaD2PHGC3G4kEPA2UQZZlVxEVZ09h9UCMA8SYKEQfqj3xDyPtaPsrpSDhVyaf5Ry +YhNcnkJj4A5UTvn4EH1MEIAj2qjMH+6CgkHGBDXOeOfRJLZXEHxO+f37CoODtaF8 +8C+rRYhy61OYY9kUBIAYfAEaHaoP9HU/BWO1yWPPnCG1FVjkOkbW6QDOqVn9w1bl +RlqWR9fLihYKg2hgI9p1TYmK7grIMmLopFvemj4ocoaU7sFm3DxELg8qMryz94UF +jLbsctL2AmJCz8tNGcQyH8F1I3ebgMWyBe7Yba4G/hvR48S1OIMgAZYLUfjlnLzw +3p8XgNqRxPFngLAKkphz +=GyQk -----END PGP SIGNATURE----- diff --git a/dev-libs/icu/files/icu-54.1-CVE-2014-9654.patch b/dev-libs/icu/files/icu-54.1-CVE-2014-9654.patch new file mode 100644 index 000000000000..db86c921bc8c --- /dev/null +++ b/dev-libs/icu/files/icu-54.1-CVE-2014-9654.patch @@ -0,0 +1,1105 @@ +Index: /icu/trunk/source/common/unicode/utypes.h +=================================================================== +--- /icu/trunk/source/common/unicode/utypes.h (revision 36800) ++++ /icu/trunk/source/common/unicode/utypes.h (revision 36801) +@@ -648,4 +648,5 @@ + U_REGEX_TIME_OUT, /**< Maximum allowed match time exceeded */ + U_REGEX_STOPPED_BY_CALLER, /**< Matching operation aborted by user callback fn. */ ++ U_REGEX_PATTERN_TOO_BIG, /**< Pattern exceeds limits on size or complexity. @draft ICU 55 */ + U_REGEX_ERROR_LIMIT, /**< This must always be the last value to indicate the limit for regexp errors */ + +Index: /icu/trunk/source/common/utypes.c +=================================================================== +--- /icu/trunk/source/common/utypes.c (revision 36800) ++++ /icu/trunk/source/common/utypes.c (revision 36801) +@@ -2,5 +2,5 @@ + ****************************************************************************** + * +-* Copyright (C) 1997-2011, International Business Machines ++* Copyright (C) 1997-2014, International Business Machines + * Corporation and others. All Rights Reserved. + * +@@ -166,5 +166,6 @@ + "U_REGEX_STACK_OVERFLOW", + "U_REGEX_TIME_OUT", +- "U_REGEX_STOPPED_BY_CALLER" ++ "U_REGEX_STOPPED_BY_CALLER", ++ "U_REGEX_PATTERN_TOO_BIG" + }; + +Index: /icu/trunk/source/i18n/regexcmp.cpp +=================================================================== +--- /icu/trunk/source/i18n/regexcmp.cpp (revision 36800) ++++ /icu/trunk/source/i18n/regexcmp.cpp (revision 36801) +@@ -305,5 +305,5 @@ + // the position in the compiled pattern. + // +- fRXPat->fFrameSize+=RESTACKFRAME_HDRCOUNT; ++ allocateStackData(RESTACKFRAME_HDRCOUNT); + + // +@@ -371,7 +371,7 @@ + //4 NOP Resreved, will be replaced by a save if there are + // OR | operators at the top level +- fRXPat->fCompiledPat->addElement(URX_BUILD(URX_STATE_SAVE, 2), *fStatus); +- fRXPat->fCompiledPat->addElement(URX_BUILD(URX_JMP, 3), *fStatus); +- fRXPat->fCompiledPat->addElement(URX_BUILD(URX_FAIL, 0), *fStatus); ++ appendOp(URX_STATE_SAVE, 2); ++ appendOp(URX_JMP, 3); ++ appendOp(URX_FAIL, 0); + + // Standard open nonCapture paren action emits the two NOPs and +@@ -396,5 +396,5 @@ + + // add the END operation to the compiled pattern. +- fRXPat->fCompiledPat->addElement(URX_BUILD(URX_END, 0), *fStatus); ++ appendOp(URX_END, 0); + + // Terminate the pattern compilation state machine. +@@ -418,5 +418,5 @@ + int32_t op = (int32_t)fRXPat->fCompiledPat->elementAti(savePosition); + U_ASSERT(URX_TYPE(op) == URX_NOP); // original contents of reserved location +- op = URX_BUILD(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+1); ++ op = buildOp(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+1); + fRXPat->fCompiledPat->setElementAt(op, savePosition); + +@@ -424,6 +424,5 @@ + // the JMP will eventually be the location following the ')' for the + // group. This will be patched in later, when the ')' is encountered. +- op = URX_BUILD(URX_JMP, 0); +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ appendOp(URX_JMP, 0); + + // Push the position of the newly added JMP op onto the parentheses stack. +@@ -434,5 +433,5 @@ + // for a SAVE in the event that there is yet another '|' following + // this one. +- fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus); ++ appendOp(URX_NOP, 0); + fParenStack.push(fRXPat->fCompiledPat->size()-1, *fStatus); + } +@@ -460,10 +459,8 @@ + { + fixLiterals(); +- fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus); +- int32_t varsLoc = fRXPat->fFrameSize; // Reserve three slots in match stack frame. +- fRXPat->fFrameSize += 3; +- int32_t cop = URX_BUILD(URX_START_CAPTURE, varsLoc); +- fRXPat->fCompiledPat->addElement(cop, *fStatus); +- fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus); ++ appendOp(URX_NOP, 0); ++ int32_t varsLoc = allocateStackData(3); // Reserve three slots in match stack frame. ++ appendOp(URX_START_CAPTURE, varsLoc); ++ appendOp(URX_NOP, 0); + + // On the Parentheses stack, start a new frame and add the postions +@@ -490,6 +487,6 @@ + { + fixLiterals(); +- fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus); +- fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus); ++ appendOp(URX_NOP, 0); ++ appendOp(URX_NOP, 0); + + // On the Parentheses stack, start a new frame and add the postions +@@ -513,10 +510,8 @@ + { + fixLiterals(); +- fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus); +- int32_t varLoc = fRXPat->fDataSize; // Reserve a data location for saving the +- fRXPat->fDataSize += 1; // state stack ptr. +- int32_t stoOp = URX_BUILD(URX_STO_SP, varLoc); +- fRXPat->fCompiledPat->addElement(stoOp, *fStatus); +- fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus); ++ appendOp(URX_NOP, 0); ++ int32_t varLoc = allocateData(1); // Reserve a data location for saving the state stack ptr. ++ appendOp(URX_STO_SP, varLoc); ++ appendOp(URX_NOP, 0); + + // On the Parentheses stack, start a new frame and add the postions +@@ -561,24 +556,12 @@ + { + fixLiterals(); +- int32_t dataLoc = fRXPat->fDataSize; +- fRXPat->fDataSize += 2; +- int32_t op = URX_BUILD(URX_LA_START, dataLoc); +- fRXPat->fCompiledPat->addElement(op, *fStatus); +- +- op = URX_BUILD(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+ 2); +- fRXPat->fCompiledPat->addElement(op, *fStatus); +- +- op = URX_BUILD(URX_JMP, fRXPat->fCompiledPat->size()+ 3); +- fRXPat->fCompiledPat->addElement(op, *fStatus); +- +- op = URX_BUILD(URX_LA_END, dataLoc); +- fRXPat->fCompiledPat->addElement(op, *fStatus); +- +- op = URX_BUILD(URX_BACKTRACK, 0); +- fRXPat->fCompiledPat->addElement(op, *fStatus); +- +- op = URX_BUILD(URX_NOP, 0); +- fRXPat->fCompiledPat->addElement(op, *fStatus); +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ int32_t dataLoc = allocateData(2); ++ appendOp(URX_LA_START, dataLoc); ++ appendOp(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+ 2); ++ appendOp(URX_JMP, fRXPat->fCompiledPat->size()+ 3); ++ appendOp(URX_LA_END, dataLoc); ++ appendOp(URX_BACKTRACK, 0); ++ appendOp(URX_NOP, 0); ++ appendOp(URX_NOP, 0); + + // On the Parentheses stack, start a new frame and add the postions +@@ -605,14 +588,8 @@ + { + fixLiterals(); +- int32_t dataLoc = fRXPat->fDataSize; +- fRXPat->fDataSize += 2; +- int32_t op = URX_BUILD(URX_LA_START, dataLoc); +- fRXPat->fCompiledPat->addElement(op, *fStatus); +- +- op = URX_BUILD(URX_STATE_SAVE, 0); // dest address will be patched later. +- fRXPat->fCompiledPat->addElement(op, *fStatus); +- +- op = URX_BUILD(URX_NOP, 0); +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ int32_t dataLoc = allocateData(2); ++ appendOp(URX_LA_START, dataLoc); ++ appendOp(URX_STATE_SAVE, 0); // dest address will be patched later. ++ appendOp(URX_NOP, 0); + + // On the Parentheses stack, start a new frame and add the postions +@@ -652,21 +629,17 @@ + + // Allocate data space +- int32_t dataLoc = fRXPat->fDataSize; +- fRXPat->fDataSize += 4; ++ int32_t dataLoc = allocateData(4); + + // Emit URX_LB_START +- int32_t op = URX_BUILD(URX_LB_START, dataLoc); +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ appendOp(URX_LB_START, dataLoc); + + // Emit URX_LB_CONT +- op = URX_BUILD(URX_LB_CONT, dataLoc); +- fRXPat->fCompiledPat->addElement(op, *fStatus); +- fRXPat->fCompiledPat->addElement(0, *fStatus); // MinMatchLength. To be filled later. +- fRXPat->fCompiledPat->addElement(0, *fStatus); // MaxMatchLength. To be filled later. +- +- // Emit the NOP +- op = URX_BUILD(URX_NOP, 0); +- fRXPat->fCompiledPat->addElement(op, *fStatus); +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ appendOp(URX_LB_CONT, dataLoc); ++ appendOp(URX_RESERVED_OP, 0); // MinMatchLength. To be filled later. ++ appendOp(URX_RESERVED_OP, 0); // MaxMatchLength. To be filled later. ++ ++ // Emit the NOPs ++ appendOp(URX_NOP, 0); ++ appendOp(URX_NOP, 0); + + // On the Parentheses stack, start a new frame and add the postions +@@ -708,22 +681,18 @@ + + // Allocate data space +- int32_t dataLoc = fRXPat->fDataSize; +- fRXPat->fDataSize += 4; ++ int32_t dataLoc = allocateData(4); + + // Emit URX_LB_START +- int32_t op = URX_BUILD(URX_LB_START, dataLoc); +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ appendOp(URX_LB_START, dataLoc); + + // Emit URX_LBN_CONT +- op = URX_BUILD(URX_LBN_CONT, dataLoc); +- fRXPat->fCompiledPat->addElement(op, *fStatus); +- fRXPat->fCompiledPat->addElement(0, *fStatus); // MinMatchLength. To be filled later. +- fRXPat->fCompiledPat->addElement(0, *fStatus); // MaxMatchLength. To be filled later. +- fRXPat->fCompiledPat->addElement(0, *fStatus); // Continue Loc. To be filled later. +- +- // Emit the NOP +- op = URX_BUILD(URX_NOP, 0); +- fRXPat->fCompiledPat->addElement(op, *fStatus); +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ appendOp(URX_LBN_CONT, dataLoc); ++ appendOp(URX_RESERVED_OP, 0); // MinMatchLength. To be filled later. ++ appendOp(URX_RESERVED_OP, 0); // MaxMatchLength. To be filled later. ++ appendOp(URX_RESERVED_OP, 0); // Continue Loc. To be filled later. ++ ++ // Emit the NOPs ++ appendOp(URX_NOP, 0); ++ appendOp(URX_NOP, 0); + + // On the Parentheses stack, start a new frame and add the postions +@@ -795,10 +764,7 @@ + if (URX_TYPE(repeatedOp) == URX_SETREF) { + // Emit optimized code for [char set]+ +- int32_t loopOpI = URX_BUILD(URX_LOOP_SR_I, URX_VAL(repeatedOp)); +- fRXPat->fCompiledPat->addElement(loopOpI, *fStatus); +- frameLoc = fRXPat->fFrameSize; +- fRXPat->fFrameSize++; +- int32_t loopOpC = URX_BUILD(URX_LOOP_C, frameLoc); +- fRXPat->fCompiledPat->addElement(loopOpC, *fStatus); ++ appendOp(URX_LOOP_SR_I, URX_VAL(repeatedOp)); ++ frameLoc = allocateStackData(1); ++ appendOp(URX_LOOP_C, frameLoc); + break; + } +@@ -808,5 +774,5 @@ + URX_TYPE(repeatedOp) == URX_DOTANY_UNIX) { + // Emit Optimized code for .+ operations. +- int32_t loopOpI = URX_BUILD(URX_LOOP_DOT_I, 0); ++ int32_t loopOpI = buildOp(URX_LOOP_DOT_I, 0); + if (URX_TYPE(repeatedOp) == URX_DOTANY_ALL) { + // URX_LOOP_DOT_I operand is a flag indicating ". matches any" mode. +@@ -816,9 +782,7 @@ + loopOpI |= 2; + } +- fRXPat->fCompiledPat->addElement(loopOpI, *fStatus); +- frameLoc = fRXPat->fFrameSize; +- fRXPat->fFrameSize++; +- int32_t loopOpC = URX_BUILD(URX_LOOP_C, frameLoc); +- fRXPat->fCompiledPat->addElement(loopOpC, *fStatus); ++ appendOp(loopOpI); ++ frameLoc = allocateStackData(1); ++ appendOp(URX_LOOP_C, frameLoc); + break; + } +@@ -834,16 +798,13 @@ + // Emit the code sequence that can handle it. + insertOp(topLoc); +- frameLoc = fRXPat->fFrameSize; +- fRXPat->fFrameSize++; +- +- int32_t op = URX_BUILD(URX_STO_INP_LOC, frameLoc); ++ frameLoc = allocateStackData(1); ++ ++ int32_t op = buildOp(URX_STO_INP_LOC, frameLoc); + fRXPat->fCompiledPat->setElementAt(op, topLoc); + +- op = URX_BUILD(URX_JMP_SAV_X, topLoc+1); +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ appendOp(URX_JMP_SAV_X, topLoc+1); + } else { + // Simpler code when the repeated body must match something non-empty +- int32_t jmpOp = URX_BUILD(URX_JMP_SAV, topLoc); +- fRXPat->fCompiledPat->addElement(jmpOp, *fStatus); ++ appendOp(URX_JMP_SAV, topLoc); + } + } +@@ -857,6 +818,5 @@ + { + int32_t topLoc = blockTopLoc(FALSE); +- int32_t saveStateOp = URX_BUILD(URX_STATE_SAVE, topLoc); +- fRXPat->fCompiledPat->addElement(saveStateOp, *fStatus); ++ appendOp(URX_STATE_SAVE, topLoc); + } + break; +@@ -872,5 +832,5 @@ + { + int32_t saveStateLoc = blockTopLoc(TRUE); +- int32_t saveStateOp = URX_BUILD(URX_STATE_SAVE, fRXPat->fCompiledPat->size()); ++ int32_t saveStateOp = buildOp(URX_STATE_SAVE, fRXPat->fCompiledPat->size()); + fRXPat->fCompiledPat->setElementAt(saveStateOp, saveStateLoc); + } +@@ -891,12 +851,10 @@ + int32_t jmp2_loc = fRXPat->fCompiledPat->size(); + +- int32_t jmp1_op = URX_BUILD(URX_JMP, jmp2_loc+1); ++ int32_t jmp1_op = buildOp(URX_JMP, jmp2_loc+1); + fRXPat->fCompiledPat->setElementAt(jmp1_op, jmp1_loc); + +- int32_t jmp2_op = URX_BUILD(URX_JMP, jmp2_loc+2); +- fRXPat->fCompiledPat->addElement(jmp2_op, *fStatus); +- +- int32_t save_op = URX_BUILD(URX_STATE_SAVE, jmp1_loc+1); +- fRXPat->fCompiledPat->addElement(save_op, *fStatus); ++ appendOp(URX_JMP, jmp2_loc+2); ++ ++ appendOp(URX_STATE_SAVE, jmp1_loc+1); + } + break; +@@ -938,10 +896,8 @@ + if (URX_TYPE(repeatedOp) == URX_SETREF) { + // Emit optimized code for a [char set]* +- int32_t loopOpI = URX_BUILD(URX_LOOP_SR_I, URX_VAL(repeatedOp)); ++ int32_t loopOpI = buildOp(URX_LOOP_SR_I, URX_VAL(repeatedOp)); + fRXPat->fCompiledPat->setElementAt(loopOpI, topLoc); +- dataLoc = fRXPat->fFrameSize; +- fRXPat->fFrameSize++; +- int32_t loopOpC = URX_BUILD(URX_LOOP_C, dataLoc); +- fRXPat->fCompiledPat->addElement(loopOpC, *fStatus); ++ dataLoc = allocateStackData(1); ++ appendOp(URX_LOOP_C, dataLoc); + break; + } +@@ -951,5 +907,5 @@ + URX_TYPE(repeatedOp) == URX_DOTANY_UNIX) { + // Emit Optimized code for .* operations. +- int32_t loopOpI = URX_BUILD(URX_LOOP_DOT_I, 0); ++ int32_t loopOpI = buildOp(URX_LOOP_DOT_I, 0); + if (URX_TYPE(repeatedOp) == URX_DOTANY_ALL) { + // URX_LOOP_DOT_I operand is a flag indicating . matches any mode. +@@ -960,8 +916,6 @@ + } + fRXPat->fCompiledPat->setElementAt(loopOpI, topLoc); +- dataLoc = fRXPat->fFrameSize; +- fRXPat->fFrameSize++; +- int32_t loopOpC = URX_BUILD(URX_LOOP_C, dataLoc); +- fRXPat->fCompiledPat->addElement(loopOpC, *fStatus); ++ dataLoc = allocateStackData(1); ++ appendOp(URX_LOOP_C, dataLoc); + break; + } +@@ -972,5 +926,5 @@ + + int32_t saveStateLoc = blockTopLoc(TRUE); +- int32_t jmpOp = URX_BUILD(URX_JMP_SAV, saveStateLoc+1); ++ int32_t jmpOp = buildOp(URX_JMP_SAV, saveStateLoc+1); + + // Check for minimum match length of zero, which requires +@@ -978,10 +932,9 @@ + if (minMatchLength(saveStateLoc, fRXPat->fCompiledPat->size()-1) == 0) { + insertOp(saveStateLoc); +- dataLoc = fRXPat->fFrameSize; +- fRXPat->fFrameSize++; +- +- int32_t op = URX_BUILD(URX_STO_INP_LOC, dataLoc); ++ dataLoc = allocateStackData(1); ++ ++ int32_t op = buildOp(URX_STO_INP_LOC, dataLoc); + fRXPat->fCompiledPat->setElementAt(op, saveStateLoc+1); +- jmpOp = URX_BUILD(URX_JMP_SAV_X, saveStateLoc+2); ++ jmpOp = buildOp(URX_JMP_SAV_X, saveStateLoc+2); + } + +@@ -990,10 +943,10 @@ + int32_t continueLoc = fRXPat->fCompiledPat->size()+1; + +- // Put together the save state op store it into the compiled code. +- int32_t saveStateOp = URX_BUILD(URX_STATE_SAVE, continueLoc); ++ // Put together the save state op and store it into the compiled code. ++ int32_t saveStateOp = buildOp(URX_STATE_SAVE, continueLoc); + fRXPat->fCompiledPat->setElementAt(saveStateOp, saveStateLoc); + + // Append the URX_JMP_SAV or URX_JMPX operation to the compiled pattern. +- fRXPat->fCompiledPat->addElement(jmpOp, *fStatus); ++ appendOp(jmpOp); + } + break; +@@ -1009,8 +962,7 @@ + int32_t jmpLoc = blockTopLoc(TRUE); // loc 1. + int32_t saveLoc = fRXPat->fCompiledPat->size(); // loc 3. +- int32_t jmpOp = URX_BUILD(URX_JMP, saveLoc); +- int32_t stateSaveOp = URX_BUILD(URX_STATE_SAVE, jmpLoc+1); ++ int32_t jmpOp = buildOp(URX_JMP, saveLoc); + fRXPat->fCompiledPat->setElementAt(jmpOp, jmpLoc); +- fRXPat->fCompiledPat->addElement(stateSaveOp, *fStatus); ++ appendOp(URX_STATE_SAVE, jmpLoc+1); + } + break; +@@ -1085,7 +1037,7 @@ + // First the STO_SP before the start of the loop + insertOp(topLoc); +- int32_t varLoc = fRXPat->fDataSize; // Reserve a data location for saving the +- fRXPat->fDataSize += 1; // state stack ptr. +- int32_t op = URX_BUILD(URX_STO_SP, varLoc); ++ ++ int32_t varLoc = allocateData(1); // Reserve a data location for saving the ++ int32_t op = buildOp(URX_STO_SP, varLoc); + fRXPat->fCompiledPat->setElementAt(op, topLoc); + +@@ -1096,6 +1048,5 @@ + + // Then the LD_SP after the end of the loop +- op = URX_BUILD(URX_LD_SP, varLoc); +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ appendOp(URX_LD_SP, varLoc); + } + +@@ -1133,13 +1084,11 @@ + { + fixLiterals(FALSE); +- int32_t op; + if (fModeFlags & UREGEX_DOTALL) { +- op = URX_BUILD(URX_DOTANY_ALL, 0); ++ appendOp(URX_DOTANY_ALL, 0); + } else if (fModeFlags & UREGEX_UNIX_LINES) { +- op = URX_BUILD(URX_DOTANY_UNIX, 0); ++ appendOp(URX_DOTANY_UNIX, 0); + } else { +- op = URX_BUILD(URX_DOTANY, 0); +- } +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ appendOp(URX_DOTANY, 0); ++ } + } + break; +@@ -1148,15 +1097,13 @@ + { + fixLiterals(FALSE); +- int32_t op = 0; + if ( (fModeFlags & UREGEX_MULTILINE) == 0 && (fModeFlags & UREGEX_UNIX_LINES) == 0) { +- op = URX_CARET; ++ appendOp(URX_CARET, 0); + } else if ((fModeFlags & UREGEX_MULTILINE) != 0 && (fModeFlags & UREGEX_UNIX_LINES) == 0) { +- op = URX_CARET_M; ++ appendOp(URX_CARET_M, 0); + } else if ((fModeFlags & UREGEX_MULTILINE) == 0 && (fModeFlags & UREGEX_UNIX_LINES) != 0) { +- op = URX_CARET; // Only testing true start of input. ++ appendOp(URX_CARET, 0); // Only testing true start of input. + } else if ((fModeFlags & UREGEX_MULTILINE) != 0 && (fModeFlags & UREGEX_UNIX_LINES) != 0) { +- op = URX_CARET_M_UNIX; +- } +- fRXPat->fCompiledPat->addElement(URX_BUILD(op, 0), *fStatus); ++ appendOp(URX_CARET_M_UNIX, 0); ++ } + } + break; +@@ -1165,15 +1112,13 @@ + { + fixLiterals(FALSE); +- int32_t op = 0; + if ( (fModeFlags & UREGEX_MULTILINE) == 0 && (fModeFlags & UREGEX_UNIX_LINES) == 0) { +- op = URX_DOLLAR; ++ appendOp(URX_DOLLAR, 0); + } else if ((fModeFlags & UREGEX_MULTILINE) != 0 && (fModeFlags & UREGEX_UNIX_LINES) == 0) { +- op = URX_DOLLAR_M; ++ appendOp(URX_DOLLAR_M, 0); + } else if ((fModeFlags & UREGEX_MULTILINE) == 0 && (fModeFlags & UREGEX_UNIX_LINES) != 0) { +- op = URX_DOLLAR_D; ++ appendOp(URX_DOLLAR_D, 0); + } else if ((fModeFlags & UREGEX_MULTILINE) != 0 && (fModeFlags & UREGEX_UNIX_LINES) != 0) { +- op = URX_DOLLAR_MD; +- } +- fRXPat->fCompiledPat->addElement(URX_BUILD(op, 0), *fStatus); ++ appendOp(URX_DOLLAR_MD, 0); ++ } + } + break; +@@ -1181,5 +1126,5 @@ + case doBackslashA: + fixLiterals(FALSE); +- fRXPat->fCompiledPat->addElement(URX_BUILD(URX_CARET, 0), *fStatus); ++ appendOp(URX_CARET, 0); + break; + +@@ -1193,5 +1138,5 @@ + fixLiterals(FALSE); + int32_t op = (fModeFlags & UREGEX_UWORD)? URX_BACKSLASH_BU : URX_BACKSLASH_B; +- fRXPat->fCompiledPat->addElement(URX_BUILD(op, 1), *fStatus); ++ appendOp(op, 1); + } + break; +@@ -1206,5 +1151,5 @@ + fixLiterals(FALSE); + int32_t op = (fModeFlags & UREGEX_UWORD)? URX_BACKSLASH_BU : URX_BACKSLASH_B; +- fRXPat->fCompiledPat->addElement(URX_BUILD(op, 0), *fStatus); ++ appendOp(op, 0); + } + break; +@@ -1212,44 +1157,40 @@ + case doBackslashD: + fixLiterals(FALSE); +- fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKSLASH_D, 1), *fStatus); ++ appendOp(URX_BACKSLASH_D, 1); + break; + + case doBackslashd: + fixLiterals(FALSE); +- fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKSLASH_D, 0), *fStatus); ++ appendOp(URX_BACKSLASH_D, 0); + break; + + case doBackslashG: + fixLiterals(FALSE); +- fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKSLASH_G, 0), *fStatus); ++ appendOp(URX_BACKSLASH_G, 0); + break; + + case doBackslashS: + fixLiterals(FALSE); +- fRXPat->fCompiledPat->addElement( +- URX_BUILD(URX_STAT_SETREF_N, URX_ISSPACE_SET), *fStatus); ++ appendOp(URX_STAT_SETREF_N, URX_ISSPACE_SET); + break; + + case doBackslashs: + fixLiterals(FALSE); +- fRXPat->fCompiledPat->addElement( +- URX_BUILD(URX_STATIC_SETREF, URX_ISSPACE_SET), *fStatus); ++ appendOp(URX_STATIC_SETREF, URX_ISSPACE_SET); + break; + + case doBackslashW: + fixLiterals(FALSE); +- fRXPat->fCompiledPat->addElement( +- URX_BUILD(URX_STAT_SETREF_N, URX_ISWORD_SET), *fStatus); ++ appendOp(URX_STAT_SETREF_N, URX_ISWORD_SET); + break; + + case doBackslashw: + fixLiterals(FALSE); +- fRXPat->fCompiledPat->addElement( +- URX_BUILD(URX_STATIC_SETREF, URX_ISWORD_SET), *fStatus); ++ appendOp(URX_STATIC_SETREF, URX_ISWORD_SET); + break; + + case doBackslashX: + fixLiterals(FALSE); +- fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKSLASH_X, 0), *fStatus); ++ appendOp(URX_BACKSLASH_X, 0); + break; + +@@ -1257,10 +1198,10 @@ + case doBackslashZ: + fixLiterals(FALSE); +- fRXPat->fCompiledPat->addElement(URX_BUILD(URX_DOLLAR, 0), *fStatus); ++ appendOp(URX_DOLLAR, 0); + break; + + case doBackslashz: + fixLiterals(FALSE); +- fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKSLASH_Z, 0), *fStatus); ++ appendOp(URX_BACKSLASH_Z, 0); + break; + +@@ -1322,11 +1263,9 @@ + // and shouldn't enter this code path at all. + fixLiterals(FALSE); +- int32_t op; + if (fModeFlags & UREGEX_CASE_INSENSITIVE) { +- op = URX_BUILD(URX_BACKREF_I, groupNum); ++ appendOp(URX_BACKREF_I, groupNum); + } else { +- op = URX_BUILD(URX_BACKREF, groupNum); +- } +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ appendOp(URX_BACKREF, groupNum); ++ } + } + break; +@@ -1349,20 +1288,16 @@ + // Emit the STO_SP + int32_t topLoc = blockTopLoc(TRUE); +- int32_t stoLoc = fRXPat->fDataSize; +- fRXPat->fDataSize++; // Reserve the data location for storing save stack ptr. +- int32_t op = URX_BUILD(URX_STO_SP, stoLoc); ++ int32_t stoLoc = allocateData(1); // Reserve the data location for storing save stack ptr. ++ int32_t op = buildOp(URX_STO_SP, stoLoc); + fRXPat->fCompiledPat->setElementAt(op, topLoc); + + // Emit the STATE_SAVE +- op = URX_BUILD(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+2); +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ appendOp(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+2); + + // Emit the JMP +- op = URX_BUILD(URX_JMP, topLoc+1); +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ appendOp(URX_JMP, topLoc+1); + + // Emit the LD_SP +- op = URX_BUILD(URX_LD_SP, stoLoc); +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ appendOp(URX_LD_SP, stoLoc); + } + break; +@@ -1384,21 +1319,18 @@ + + // emit STO_SP loc +- int32_t stoLoc = fRXPat->fDataSize; +- fRXPat->fDataSize++; // Reserve the data location for storing save stack ptr. +- int32_t op = URX_BUILD(URX_STO_SP, stoLoc); ++ int32_t stoLoc = allocateData(1); // Reserve the data location for storing save stack ptr. ++ int32_t op = buildOp(URX_STO_SP, stoLoc); + fRXPat->fCompiledPat->setElementAt(op, topLoc); + + // Emit the SAVE_STATE 5 + int32_t L7 = fRXPat->fCompiledPat->size()+1; +- op = URX_BUILD(URX_STATE_SAVE, L7); ++ op = buildOp(URX_STATE_SAVE, L7); + fRXPat->fCompiledPat->setElementAt(op, topLoc+1); + + // Append the JMP operation. +- op = URX_BUILD(URX_JMP, topLoc+1); +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ appendOp(URX_JMP, topLoc+1); + + // Emit the LD_SP loc +- op = URX_BUILD(URX_LD_SP, stoLoc); +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ appendOp(URX_LD_SP, stoLoc); + } + break; +@@ -1419,17 +1351,15 @@ + + // Emit the STO_SP +- int32_t stoLoc = fRXPat->fDataSize; +- fRXPat->fDataSize++; // Reserve the data location for storing save stack ptr. +- int32_t op = URX_BUILD(URX_STO_SP, stoLoc); ++ int32_t stoLoc = allocateData(1); // Reserve the data location for storing save stack ptr. ++ int32_t op = buildOp(URX_STO_SP, stoLoc); + fRXPat->fCompiledPat->setElementAt(op, topLoc); + + // Emit the SAVE_STATE + int32_t continueLoc = fRXPat->fCompiledPat->size()+1; +- op = URX_BUILD(URX_STATE_SAVE, continueLoc); ++ op = buildOp(URX_STATE_SAVE, continueLoc); + fRXPat->fCompiledPat->setElementAt(op, topLoc+1); + + // Emit the LD_SP +- op = URX_BUILD(URX_LD_SP, stoLoc); +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ appendOp(URX_LD_SP, stoLoc); + } + break; +@@ -1488,6 +1418,6 @@ + { + fixLiterals(FALSE); +- fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus); +- fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus); ++ appendOp(URX_NOP, 0); ++ appendOp(URX_NOP, 0); + + // On the Parentheses stack, start a new frame and add the postions +@@ -1826,5 +1756,4 @@ + //------------------------------------------------------------------------------ + void RegexCompile::fixLiterals(UBool split) { +- int32_t op = 0; // An op from/for the compiled pattern. + + // If no literal characters have been scanned but not yet had code generated +@@ -1865,21 +1794,21 @@ + if ((fModeFlags & UREGEX_CASE_INSENSITIVE) && + u_hasBinaryProperty(lastCodePoint, UCHAR_CASE_SENSITIVE)) { +- op = URX_BUILD(URX_ONECHAR_I, lastCodePoint); ++ appendOp(URX_ONECHAR_I, lastCodePoint); + } else { +- op = URX_BUILD(URX_ONECHAR, lastCodePoint); +- } +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ appendOp(URX_ONECHAR, lastCodePoint); ++ } + } else { + // Two or more chars, emit a URX_STRING to match them. ++ if (fLiteralChars.length() > 0x00ffffff || fRXPat->fLiteralText.length() > 0x00ffffff) { ++ error(U_REGEX_PATTERN_TOO_BIG); ++ } + if (fModeFlags & UREGEX_CASE_INSENSITIVE) { +- op = URX_BUILD(URX_STRING_I, fRXPat->fLiteralText.length()); ++ appendOp(URX_STRING_I, fRXPat->fLiteralText.length()); + } else { + // TODO here: add optimization to split case sensitive strings of length two + // into two single char ops, for efficiency. +- op = URX_BUILD(URX_STRING, fRXPat->fLiteralText.length()); +- } +- fRXPat->fCompiledPat->addElement(op, *fStatus); +- op = URX_BUILD(URX_STRING_LEN, fLiteralChars.length()); +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ appendOp(URX_STRING, fRXPat->fLiteralText.length()); ++ } ++ appendOp(URX_STRING_LEN, fLiteralChars.length()); + + // Add this string into the accumulated strings of the compiled pattern. +@@ -1891,6 +1820,56 @@ + + +- +- ++int32_t RegexCompile::buildOp(int32_t type, int32_t val) { ++ if (U_FAILURE(*fStatus)) { ++ return 0; ++ } ++ if (type < 0 || type > 255) { ++ U_ASSERT(FALSE); ++ error(U_REGEX_INTERNAL_ERROR); ++ type = URX_RESERVED_OP; ++ } ++ if (val > 0x00ffffff) { ++ U_ASSERT(FALSE); ++ error(U_REGEX_INTERNAL_ERROR); ++ val = 0; ++ } ++ if (val < 0) { ++ if (!(type == URX_RESERVED_OP_N || type == URX_RESERVED_OP)) { ++ U_ASSERT(FALSE); ++ error(U_REGEX_INTERNAL_ERROR); ++ return -1; ++ } ++ if (URX_TYPE(val) != 0xff) { ++ U_ASSERT(FALSE); ++ error(U_REGEX_INTERNAL_ERROR); ++ return -1; ++ } ++ type = URX_RESERVED_OP_N; ++ } ++ return (type << 24) | val; ++} ++ ++ ++//------------------------------------------------------------------------------ ++// ++// appendOp() Append a new instruction onto the compiled pattern ++// Includes error checking, limiting the size of the ++// pattern to lengths that can be represented in the ++// 24 bit operand field of an instruction. ++// ++//------------------------------------------------------------------------------ ++void RegexCompile::appendOp(int32_t op) { ++ if (U_FAILURE(*fStatus)) { ++ return; ++ } ++ fRXPat->fCompiledPat->addElement(op, *fStatus); ++ if ((fRXPat->fCompiledPat->size() > 0x00fffff0) && U_SUCCESS(*fStatus)) { ++ error(U_REGEX_PATTERN_TOO_BIG); ++ } ++} ++ ++void RegexCompile::appendOp(int32_t type, int32_t val) { ++ appendOp(buildOp(type, val)); ++} + + +@@ -1908,5 +1887,5 @@ + U_ASSERT(where>0 && where < code->size()); + +- int32_t nop = URX_BUILD(URX_NOP, 0); ++ int32_t nop = buildOp(URX_NOP, 0); + code->insertElementAt(nop, where, *fStatus); + +@@ -1929,5 +1908,5 @@ + // needs to be incremented to adjust for the insertion. + opValue++; +- op = URX_BUILD(opType, opValue); ++ op = buildOp(opType, opValue); + code->setElementAt(op, loc); + } +@@ -1953,4 +1932,56 @@ + } + ++ ++//------------------------------------------------------------------------------ ++// ++// allocateData() Allocate storage in the matcher's static data area. ++// Return the index for the newly allocated data. ++// The storage won't actually exist until we are running a match ++// operation, but the storage indexes are inserted into various ++// opcodes while compiling the pattern. ++// ++//------------------------------------------------------------------------------ ++int32_t RegexCompile::allocateData(int32_t size) { ++ if (U_FAILURE(*fStatus)) { ++ return 0; ++ } ++ if (size <= 0 || size > 0x100 || fRXPat->fDataSize < 0) { ++ error(U_REGEX_INTERNAL_ERROR); ++ return 0; ++ } ++ int32_t dataIndex = fRXPat->fDataSize; ++ fRXPat->fDataSize += size; ++ if (fRXPat->fDataSize >= 0x00fffff0) { ++ error(U_REGEX_INTERNAL_ERROR); ++ } ++ return dataIndex; ++} ++ ++ ++//------------------------------------------------------------------------------ ++// ++// allocateStackData() Allocate space in the back-tracking stack frame. ++// Return the index for the newly allocated data. ++// The frame indexes are inserted into various ++// opcodes while compiling the pattern, meaning that frame ++// size must be restricted to the size that will fit ++// as an operand (24 bits). ++// ++//------------------------------------------------------------------------------ ++int32_t RegexCompile::allocateStackData(int32_t size) { ++ if (U_FAILURE(*fStatus)) { ++ return 0; ++ } ++ if (size <= 0 || size > 0x100 || fRXPat->fFrameSize < 0) { ++ error(U_REGEX_INTERNAL_ERROR); ++ return 0; ++ } ++ int32_t dataIndex = fRXPat->fFrameSize; ++ fRXPat->fFrameSize += size; ++ if (fRXPat->fFrameSize >= 0x00fffff0) { ++ error(U_REGEX_PATTERN_TOO_BIG); ++ } ++ return dataIndex; ++} + + +@@ -1996,5 +2027,5 @@ + } + if (reserveLoc) { +- int32_t nop = URX_BUILD(URX_NOP, 0); ++ int32_t nop = buildOp(URX_NOP, 0); + fRXPat->fCompiledPat->insertElementAt(nop, theLoc, *fStatus); + } +@@ -2071,6 +2102,5 @@ + + int32_t frameVarLocation = URX_VAL(captureOp); +- int32_t endCaptureOp = URX_BUILD(URX_END_CAPTURE, frameVarLocation); +- fRXPat->fCompiledPat->addElement(endCaptureOp, *fStatus); ++ appendOp(URX_END_CAPTURE, frameVarLocation); + } + break; +@@ -2083,6 +2113,5 @@ + U_ASSERT(URX_TYPE(stoOp) == URX_STO_SP); + int32_t stoLoc = URX_VAL(stoOp); +- int32_t ldOp = URX_BUILD(URX_LD_SP, stoLoc); +- fRXPat->fCompiledPat->addElement(ldOp, *fStatus); ++ appendOp(URX_LD_SP, stoLoc); + } + break; +@@ -2093,6 +2122,5 @@ + U_ASSERT(URX_TYPE(startOp) == URX_LA_START); + int32_t dataLoc = URX_VAL(startOp); +- int32_t op = URX_BUILD(URX_LA_END, dataLoc); +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ appendOp(URX_LA_END, dataLoc); + } + break; +@@ -2104,10 +2132,7 @@ + U_ASSERT(URX_TYPE(startOp) == URX_LA_START); + int32_t dataLoc = URX_VAL(startOp); +- int32_t op = URX_BUILD(URX_LA_END, dataLoc); +- fRXPat->fCompiledPat->addElement(op, *fStatus); +- op = URX_BUILD(URX_BACKTRACK, 0); +- fRXPat->fCompiledPat->addElement(op, *fStatus); +- op = URX_BUILD(URX_LA_END, dataLoc); +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ appendOp(URX_LA_END, dataLoc); ++ appendOp(URX_BACKTRACK, 0); ++ appendOp(URX_LA_END, dataLoc); + + // Patch the URX_SAVE near the top of the block. +@@ -2116,5 +2141,5 @@ + U_ASSERT(URX_TYPE(saveOp) == URX_STATE_SAVE); + int32_t dest = fRXPat->fCompiledPat->size()-1; +- saveOp = URX_BUILD(URX_STATE_SAVE, dest); ++ saveOp = buildOp(URX_STATE_SAVE, dest); + fRXPat->fCompiledPat->setElementAt(saveOp, fMatchOpenParen); + } +@@ -2129,8 +2154,6 @@ + U_ASSERT(URX_TYPE(startOp) == URX_LB_START); + int32_t dataLoc = URX_VAL(startOp); +- int32_t op = URX_BUILD(URX_LB_END, dataLoc); +- fRXPat->fCompiledPat->addElement(op, *fStatus); +- op = URX_BUILD(URX_LA_END, dataLoc); +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ appendOp(URX_LB_END, dataLoc); ++ appendOp(URX_LA_END, dataLoc); + + // Determine the min and max bounds for the length of the +@@ -2168,6 +2191,5 @@ + U_ASSERT(URX_TYPE(startOp) == URX_LB_START); + int32_t dataLoc = URX_VAL(startOp); +- int32_t op = URX_BUILD(URX_LBN_END, dataLoc); +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ appendOp(URX_LBN_END, dataLoc); + + // Determine the min and max bounds for the length of the +@@ -2194,5 +2216,5 @@ + // Insert the pattern location to continue at after a successful match + // as the last operand of the URX_LBN_CONT +- op = URX_BUILD(URX_RELOC_OPRND, fRXPat->fCompiledPat->size()); ++ int32_t op = buildOp(URX_RELOC_OPRND, fRXPat->fCompiledPat->size()); + fRXPat->fCompiledPat->setElementAt(op, fMatchOpenParen-1); + } +@@ -2235,5 +2257,5 @@ + { + // Set of no elements. Always fails to match. +- fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKTRACK, 0), *fStatus); ++ appendOp(URX_BACKTRACK, 0); + delete theSet; + } +@@ -2256,6 +2278,5 @@ + int32_t setNumber = fRXPat->fSets->size(); + fRXPat->fSets->addElement(theSet, *fStatus); +- int32_t setOp = URX_BUILD(URX_SETREF, setNumber); +- fRXPat->fCompiledPat->addElement(setOp, *fStatus); ++ appendOp(URX_SETREF, setNumber); + } + } +@@ -2296,11 +2317,8 @@ + // +1 --> Input index (for breaking non-progressing loops) + // (Only present if unbounded upper limit on loop) +- int32_t counterLoc = fRXPat->fFrameSize; +- fRXPat->fFrameSize++; +- if (fIntervalUpper < 0) { +- fRXPat->fFrameSize++; +- } +- +- int32_t op = URX_BUILD(InitOp, counterLoc); ++ int32_t dataSize = fIntervalUpper < 0 ? 2 : 1; ++ int32_t counterLoc = allocateStackData(dataSize); ++ ++ int32_t op = buildOp(InitOp, counterLoc); + fRXPat->fCompiledPat->setElementAt(op, topOfBlock); + +@@ -2310,5 +2328,5 @@ + // position to move. + int32_t loopEnd = fRXPat->fCompiledPat->size(); +- op = URX_BUILD(URX_RELOC_OPRND, loopEnd); ++ op = buildOp(URX_RELOC_OPRND, loopEnd); + fRXPat->fCompiledPat->setElementAt(op, topOfBlock+1); + +@@ -2319,6 +2337,5 @@ + // Apend the CTR_LOOP op. The operand is the location of the CTR_INIT op. + // Goes at end of the block being looped over, so just append to the code so far. +- op = URX_BUILD(LoopOp, topOfBlock); +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ appendOp(LoopOp, topOfBlock); + + if ((fIntervalLow & 0xff000000) != 0 || +@@ -2373,5 +2390,5 @@ + int32_t endOfSequenceLoc = fRXPat->fCompiledPat->size()-1 + + fIntervalUpper + (fIntervalUpper-fIntervalLow); +- int32_t saveOp = URX_BUILD(URX_STATE_SAVE, endOfSequenceLoc); ++ int32_t saveOp = buildOp(URX_STATE_SAVE, endOfSequenceLoc); + if (fIntervalLow == 0) { + insertOp(topOfBlock); +@@ -2386,11 +2403,8 @@ + int32_t i; + for (i=1; ifCompiledPat->addElement(saveOp, *fStatus); +- } +- if (i > fIntervalLow) { +- fRXPat->fCompiledPat->addElement(saveOp, *fStatus); +- } +- fRXPat->fCompiledPat->addElement(op, *fStatus); ++ if (i >= fIntervalLow) { ++ appendOp(saveOp); ++ } ++ appendOp(op); + } + return TRUE; +@@ -3612,5 +3626,5 @@ + U_ASSERT(operandAddress>=0 && operandAddressfCompiledPat->setElementAt(op, dst); + dst++; +@@ -3627,5 +3641,5 @@ + } + where = fRXPat->fGroupMap->elementAti(where-1); +- op = URX_BUILD(opType, where); ++ op = buildOp(opType, where); + fRXPat->fCompiledPat->setElementAt(op, dst); + dst++; +@@ -3979,5 +3993,5 @@ + // + // scanNamedChar +- // Get a UChar32 from a \N{UNICODE CHARACTER NAME} in the pattern. ++// Get a UChar32 from a \N{UNICODE CHARACTER NAME} in the pattern. + // + // The scan position will be at the 'N'. On return +Index: /icu/trunk/source/i18n/regexcmp.h +=================================================================== +--- /icu/trunk/source/i18n/regexcmp.h (revision 36800) ++++ /icu/trunk/source/i18n/regexcmp.h (revision 36801) +@@ -105,4 +105,11 @@ + void insertOp(int32_t where); // Open up a slot for a new op in the + // generated code at the specified location. ++ void appendOp(int32_t op); // Append a new op to the compiled pattern. ++ void appendOp(int32_t type, int32_t val); // Build & append a new op to the compiled pattern. ++ int32_t buildOp(int32_t type, int32_t val); // Construct a new pcode instruction. ++ int32_t allocateData(int32_t size); // Allocate space in the matcher data area. ++ // Return index of the newly allocated data. ++ int32_t allocateStackData(int32_t size); // Allocate space in the match back-track stack frame. ++ // Return offset index in the frame. + int32_t minMatchLength(int32_t start, + int32_t end); +Index: /icu/trunk/source/i18n/regeximp.h +=================================================================== +--- /icu/trunk/source/i18n/regeximp.h (revision 36800) ++++ /icu/trunk/source/i18n/regeximp.h (revision 36801) +@@ -1,4 +1,4 @@ + // +-// Copyright (C) 2002-2013 International Business Machines Corporation ++// Copyright (C) 2002-2014 International Business Machines Corporation + // and others. All rights reserved. + // +@@ -242,5 +242,4 @@ + // Convenience macros for assembling and disassembling a compiled operation. + // +-#define URX_BUILD(type, val) (int32_t)((type << 24) | (val)) + #define URX_TYPE(x) ((uint32_t)(x) >> 24) + #define URX_VAL(x) ((x) & 0xffffff) +Index: /icu/trunk/source/test/intltest/regextst.cpp +=================================================================== +--- /icu/trunk/source/test/intltest/regextst.cpp (revision 36800) ++++ /icu/trunk/source/test/intltest/regextst.cpp (revision 36801) +@@ -145,4 +145,7 @@ + if (exec) TestBug11049(); + break; ++ case 25: name = "TestBug11371"; ++ if (exec) TestBug11371(); ++ break; + default: name = ""; + break; //needed to end loop +@@ -5368,4 +5371,47 @@ + + ++void RegexTest::TestBug11371() { ++ if (quick) { ++ logln("Skipping test. Runs in exhuastive mode only."); ++ return; ++ } ++ UErrorCode status = U_ZERO_ERROR; ++ UnicodeString patternString; ++ ++ for (int i=0; i<8000000; i++) { ++ patternString.append(UnicodeString("()")); ++ } ++ LocalPointer compiledPat(RegexPattern::compile(patternString, 0, status)); ++ if (status != U_REGEX_PATTERN_TOO_BIG) { ++ errln("File %s, line %d expected status=U_REGEX_PATTERN_TOO_BIG; got %s.", ++ __FILE__, __LINE__, u_errorName(status)); ++ } ++ ++ status = U_ZERO_ERROR; ++ patternString = "("; ++ for (int i=0; i<20000000; i++) { ++ patternString.append(UnicodeString("A++")); ++ } ++ patternString.append(UnicodeString("){0}B++")); ++ LocalPointer compiledPat2(RegexPattern::compile(patternString, 0, status)); ++ if (status != U_REGEX_PATTERN_TOO_BIG) { ++ errln("File %s, line %d expected status=U_REGEX_PATTERN_TOO_BIG; got %s.", ++ __FILE__, __LINE__, u_errorName(status)); ++ } ++ ++ // Pattern with too much string data, such that string indexes overflow operand data field size ++ // in compiled instruction. ++ status = U_ZERO_ERROR; ++ patternString = ""; ++ while (patternString.length() < 0x00ffffff) { ++ patternString.append(UnicodeString("stuff and things dont you know, these are a few of my favorite strings\n")); ++ } ++ patternString.append(UnicodeString("X? trailing string")); ++ LocalPointer compiledPat3(RegexPattern::compile(patternString, 0, status)); ++ if (status != U_REGEX_PATTERN_TOO_BIG) { ++ errln("File %s, line %d expected status=U_REGEX_PATTERN_TOO_BIG; got %s.", ++ __FILE__, __LINE__, u_errorName(status)); ++ } ++} + + #endif /* !UCONFIG_NO_REGULAR_EXPRESSIONS */ +Index: /icu/trunk/source/test/intltest/regextst.h +=================================================================== +--- /icu/trunk/source/test/intltest/regextst.h (revision 36800) ++++ /icu/trunk/source/test/intltest/regextst.h (revision 36801) +@@ -51,4 +51,5 @@ + virtual void TestCaseInsensitiveStarters(); + virtual void TestBug11049(); ++ virtual void TestBug11371(); + + // The following functions are internal to the regexp tests. diff --git a/dev-libs/icu/icu-53.1-r1.ebuild b/dev-libs/icu/icu-53.1-r3.ebuild similarity index 94% rename from dev-libs/icu/icu-53.1-r1.ebuild rename to dev-libs/icu/icu-53.1-r3.ebuild index 27081c30b5a7..d6ab791a8324 100644 --- a/dev-libs/icu/icu-53.1-r1.ebuild +++ b/dev-libs/icu/icu-53.1-r3.ebuild @@ -1,6 +1,6 @@ # Copyright 1999-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/dev-libs/icu/icu-53.1-r1.ebuild,v 1.1 2015/01/07 07:40:43 remi Exp $ +# $Header: /var/cvsroot/gentoo-x86/dev-libs/icu/icu-53.1-r3.ebuild,v 1.1 2015/02/07 17:47:06 dilfridge Exp $ EAPI=5 @@ -12,7 +12,7 @@ SRC_URI="http://download.icu-project.org/files/icu4c/${PV/_/}/icu4c-${PV//./_}-s LICENSE="BSD" -SLOT="0/53" +SLOT="0/53a" KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86 ~amd64-fbsd ~x86-fbsd" IUSE="debug doc examples static-libs" @@ -30,6 +30,8 @@ src_prepare() { epatch "${FILESDIR}/icu-fix-tests-depending-on-date.patch" epatch "${FILESDIR}/${PN}-remove-bashisms.patch" + epatch "${FILESDIR}/${PN}-54.1-CVE-2014-9654.patch" + epatch_user # Do not hardcode flags in icu-config and icu-*.pc files. diff --git a/dev-libs/icu/icu-54.1-r1.ebuild b/dev-libs/icu/icu-54.1-r1.ebuild new file mode 100644 index 000000000000..8455ee9c448c --- /dev/null +++ b/dev-libs/icu/icu-54.1-r1.ebuild @@ -0,0 +1,134 @@ +# Copyright 1999-2015 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/dev-libs/icu/icu-54.1-r1.ebuild,v 1.1 2015/02/07 17:47:06 dilfridge Exp $ + +EAPI=5 + +inherit eutils flag-o-matic toolchain-funcs autotools multilib-minimal + +DESCRIPTION="International Components for Unicode" +HOMEPAGE="http://www.icu-project.org/" +SRC_URI="http://download.icu-project.org/files/icu4c/${PV/_/}/icu4c-${PV//./_}-src.tgz" + +LICENSE="BSD" + +SLOT="0/54a" + +KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86 ~amd64-fbsd ~x86-fbsd" +IUSE="debug doc examples static-libs" + +DEPEND=" + doc? ( + app-doc/doxygen[dot] + ) +" + +S="${WORKDIR}/${PN}/source" + +MULTILIB_CHOST_TOOLS=( + /usr/bin/icu-config +) + +src_prepare() { + local variable + + epatch "${FILESDIR}/${PN}-remove-bashisms.patch" + epatch "${FILESDIR}/${P}-CVE-2014-9654.patch" + epatch_user + + # Disable renaming as it is stupind thing to do + sed -i \ + -e "s/#define U_DISABLE_RENAMING 0/#define U_DISABLE_RENAMING 1/" \ + common/unicode/uconfig.h || die + + # Fix linking of icudata + sed -i \ + -e "s:LDFLAGSICUDT=-nodefaultlibs -nostdlib:LDFLAGSICUDT=:" \ + config/mh-linux || die + + # Append doxygen configuration to configure + sed -i \ + -e 's:icudefs.mk:icudefs.mk Doxyfile:' \ + configure.ac || die + + eautoreconf +} + +src_configure() { + # Do _not_ use C++11 yet, make sure to force GNU C++ 98 standard. + append-cxxflags -std=gnu++98 + + if tc-is-cross-compiler; then + mkdir "${WORKDIR}"/host || die + pushd "${WORKDIR}"/host >/dev/null || die + + CFLAGS="" CXXFLAGS="" ASFLAGS="" LDFLAGS="" \ + CC="$(tc-getBUILD_CC)" CXX="$(tc-getBUILD_CXX)" AR="$(tc-getBUILD_AR)" \ + RANLIB="$(tc-getBUILD_RANLIB)" LD="$(tc-getBUILD_LD)" \ + "${S}"/configure --disable-renaming --disable-debug \ + --disable-samples --enable-static || die + emake + + popd >/dev/null || die + fi + + multilib-minimal_src_configure +} + +multilib_src_configure() { + local myeconfargs=( + --disable-renaming + --disable-samples + $(use_enable debug) + $(use_enable static-libs static) + ) + + multilib_is_native_abi && myeconfargs+=( + $(use_enable examples samples) + ) + tc-is-cross-compiler && myeconfargs+=( + --with-cross-build="${WORKDIR}"/host + ) + + # icu tries to use clang by default + tc-export CC CXX + + ECONF_SOURCE=${S} \ + econf "${myeconfargs[@]}" +} + +multilib_src_compile() { + default + + if multilib_is_native_abi && use doc; then + doxygen -u Doxyfile || die + doxygen Doxyfile || die + fi +} + +multilib_src_test() { + # INTLTEST_OPTS: intltest options + # -e: Exhaustive testing + # -l: Reporting of memory leaks + # -v: Increased verbosity + # IOTEST_OPTS: iotest options + # -e: Exhaustive testing + # -v: Increased verbosity + # CINTLTST_OPTS: cintltst options + # -e: Exhaustive testing + # -v: Increased verbosity + emake -j1 VERBOSE="1" check +} + +multilib_src_install() { + default + + if multilib_is_native_abi && use doc; then + dohtml -p api -r doc/html/ + fi +} + +multilib_src_install_all() { + einstalldocs + dohtml ../readme.html +} -- 2.26.2