Backport patch for CVE-2014-9654, bug 539108. Unfortunately this does bad things...
authorAndreas Hüttel <dilfridge@gentoo.org>
Sat, 7 Feb 2015 17:47:17 +0000 (17:47 +0000)
committerAndreas Hüttel <dilfridge@gentoo.org>
Sat, 7 Feb 2015 17:47:17 +0000 (17:47 +0000)
Package-Manager: portage-2.2.15/cvs/Linux x86_64
Manifest-Sign-Key: 0x84AD142F

dev-libs/icu/ChangeLog
dev-libs/icu/Manifest
dev-libs/icu/files/icu-54.1-CVE-2014-9654.patch [new file with mode: 0644]
dev-libs/icu/icu-53.1-r3.ebuild [moved from dev-libs/icu/icu-53.1-r1.ebuild with 94% similarity]
dev-libs/icu/icu-54.1-r1.ebuild [new file with mode: 0644]

index 4dd487cea1ac20d35ab5af7fd7b477c9296dde64..b03844e4a6683e614916e8cec8a08da0c597cdbd 100644 (file)
@@ -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 <dilfridge@gentoo.org> -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)
 
index 1e3c61cc904f093281f9638d179e8266094c5aad..6be405a01714ce59f8d0be4c130e78432c91cb43 100644 (file)
@@ -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 (file)
index 0000000..db86c92
--- /dev/null
@@ -0,0 +1,1105 @@
+Index: /icu/trunk/source/common/unicode/utypes.h\r
+===================================================================\r
+--- /icu/trunk/source/common/unicode/utypes.h  (revision 36800)\r
++++ /icu/trunk/source/common/unicode/utypes.h  (revision 36801)\r
+@@ -648,4 +648,5 @@\r
+     U_REGEX_TIME_OUT,                     /**< Maximum allowed match time exceeded                */\r
+     U_REGEX_STOPPED_BY_CALLER,            /**< Matching operation aborted by user callback fn.    */\r
++    U_REGEX_PATTERN_TOO_BIG,              /**< Pattern exceeds limits on size or complexity.   @draft ICU 55   */\r
+     U_REGEX_ERROR_LIMIT,                  /**< This must always be the last value to indicate the limit for regexp errors */\r
+ \r
+Index: /icu/trunk/source/common/utypes.c\r
+===================================================================\r
+--- /icu/trunk/source/common/utypes.c  (revision 36800)\r
++++ /icu/trunk/source/common/utypes.c  (revision 36801)\r
+@@ -2,5 +2,5 @@\r
+ ******************************************************************************\r
+ *\r
+-*   Copyright (C) 1997-2011, International Business Machines\r
++*   Copyright (C) 1997-2014, International Business Machines\r
+ *   Corporation and others.  All Rights Reserved.\r
+ *\r
+@@ -166,5 +166,6 @@\r
+     "U_REGEX_STACK_OVERFLOW",\r
+     "U_REGEX_TIME_OUT",\r
+-    "U_REGEX_STOPPED_BY_CALLER"\r
++    "U_REGEX_STOPPED_BY_CALLER",\r
++    "U_REGEX_PATTERN_TOO_BIG"\r
+ };\r
+ \r
+Index: /icu/trunk/source/i18n/regexcmp.cpp\r
+===================================================================\r
+--- /icu/trunk/source/i18n/regexcmp.cpp        (revision 36800)\r
++++ /icu/trunk/source/i18n/regexcmp.cpp        (revision 36801)\r
+@@ -305,5 +305,5 @@\r
+     //   the position in the compiled pattern.\r
+     //\r
+-    fRXPat->fFrameSize+=RESTACKFRAME_HDRCOUNT;\r
++    allocateStackData(RESTACKFRAME_HDRCOUNT);\r
+ \r
+     //\r
+@@ -371,7 +371,7 @@\r
+         //4   NOP             Resreved, will be replaced by a save if there are\r
+         //                    OR | operators at the top level\r
+-        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_STATE_SAVE, 2), *fStatus);\r
+-        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_JMP,  3), *fStatus);\r
+-        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_FAIL, 0), *fStatus);\r
++        appendOp(URX_STATE_SAVE, 2);\r
++        appendOp(URX_JMP,  3);\r
++        appendOp(URX_FAIL, 0);\r
+ \r
+         // Standard open nonCapture paren action emits the two NOPs and\r
+@@ -396,5 +396,5 @@\r
+ \r
+         // add the END operation to the compiled pattern.\r
+-        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_END, 0), *fStatus);\r
++        appendOp(URX_END, 0);\r
+ \r
+         // Terminate the pattern compilation state machine.\r
+@@ -418,5 +418,5 @@\r
+             int32_t op = (int32_t)fRXPat->fCompiledPat->elementAti(savePosition);\r
+             U_ASSERT(URX_TYPE(op) == URX_NOP);  // original contents of reserved location\r
+-            op = URX_BUILD(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+1);\r
++            op = buildOp(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+1);\r
+             fRXPat->fCompiledPat->setElementAt(op, savePosition);\r
+ \r
+@@ -424,6 +424,5 @@\r
+             //  the JMP will eventually be the location following the ')' for the\r
+             //  group.  This will be patched in later, when the ')' is encountered.\r
+-            op = URX_BUILD(URX_JMP, 0);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++            appendOp(URX_JMP, 0);\r
+ \r
+             // Push the position of the newly added JMP op onto the parentheses stack.\r
+@@ -434,5 +433,5 @@\r
+             //   for a SAVE in the event that there is yet another '|' following\r
+             //   this one.\r
+-            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);\r
++            appendOp(URX_NOP, 0);\r
+             fParenStack.push(fRXPat->fCompiledPat->size()-1, *fStatus);\r
+         }\r
+@@ -460,10 +459,8 @@\r
+         {\r
+             fixLiterals();\r
+-            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);\r
+-            int32_t  varsLoc    = fRXPat->fFrameSize;    // Reserve three slots in match stack frame.\r
+-            fRXPat->fFrameSize += 3;\r
+-            int32_t  cop        = URX_BUILD(URX_START_CAPTURE, varsLoc);\r
+-            fRXPat->fCompiledPat->addElement(cop, *fStatus);\r
+-            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);\r
++            appendOp(URX_NOP, 0);\r
++            int32_t  varsLoc = allocateStackData(3);    // Reserve three slots in match stack frame.\r
++            appendOp(URX_START_CAPTURE, varsLoc);\r
++            appendOp(URX_NOP, 0);\r
+ \r
+             // On the Parentheses stack, start a new frame and add the postions\r
+@@ -490,6 +487,6 @@\r
+         {\r
+             fixLiterals();\r
+-            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);\r
+-            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);\r
++            appendOp(URX_NOP, 0);\r
++            appendOp(URX_NOP, 0);\r
+ \r
+             // On the Parentheses stack, start a new frame and add the postions\r
+@@ -513,10 +510,8 @@\r
+         {\r
+             fixLiterals();\r
+-            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);\r
+-            int32_t  varLoc    = fRXPat->fDataSize;    // Reserve a data location for saving the\r
+-            fRXPat->fDataSize += 1;                    //  state stack ptr.\r
+-            int32_t  stoOp     = URX_BUILD(URX_STO_SP, varLoc);\r
+-            fRXPat->fCompiledPat->addElement(stoOp, *fStatus);\r
+-            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);\r
++            appendOp(URX_NOP, 0);\r
++            int32_t  varLoc = allocateData(1);    // Reserve a data location for saving the state stack ptr.\r
++            appendOp(URX_STO_SP, varLoc);\r
++            appendOp(URX_NOP, 0);\r
+ \r
+             // On the Parentheses stack, start a new frame and add the postions\r
+@@ -561,24 +556,12 @@\r
+         {\r
+             fixLiterals();\r
+-            int32_t dataLoc = fRXPat->fDataSize;\r
+-            fRXPat->fDataSize += 2;\r
+-            int32_t op = URX_BUILD(URX_LA_START, dataLoc);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
+-\r
+-            op = URX_BUILD(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+ 2);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
+-\r
+-            op = URX_BUILD(URX_JMP, fRXPat->fCompiledPat->size()+ 3);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
+-\r
+-            op = URX_BUILD(URX_LA_END, dataLoc);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
+-\r
+-            op = URX_BUILD(URX_BACKTRACK, 0);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
+-\r
+-            op = URX_BUILD(URX_NOP, 0);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++            int32_t dataLoc = allocateData(2);\r
++            appendOp(URX_LA_START, dataLoc);\r
++            appendOp(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+ 2);\r
++            appendOp(URX_JMP, fRXPat->fCompiledPat->size()+ 3);\r
++            appendOp(URX_LA_END, dataLoc);\r
++            appendOp(URX_BACKTRACK, 0);\r
++            appendOp(URX_NOP, 0);\r
++            appendOp(URX_NOP, 0);\r
+ \r
+             // On the Parentheses stack, start a new frame and add the postions\r
+@@ -605,14 +588,8 @@\r
+         {\r
+             fixLiterals();\r
+-            int32_t dataLoc = fRXPat->fDataSize;\r
+-            fRXPat->fDataSize += 2;\r
+-            int32_t op = URX_BUILD(URX_LA_START, dataLoc);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
+-\r
+-            op = URX_BUILD(URX_STATE_SAVE, 0);    // dest address will be patched later.\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
+-\r
+-            op = URX_BUILD(URX_NOP, 0);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++            int32_t dataLoc = allocateData(2);\r
++            appendOp(URX_LA_START, dataLoc);\r
++            appendOp(URX_STATE_SAVE, 0);    // dest address will be patched later.\r
++            appendOp(URX_NOP, 0);\r
+ \r
+             // On the Parentheses stack, start a new frame and add the postions\r
+@@ -652,21 +629,17 @@\r
+ \r
+             // Allocate data space\r
+-            int32_t dataLoc = fRXPat->fDataSize;\r
+-            fRXPat->fDataSize += 4;\r
++            int32_t dataLoc = allocateData(4);\r
+ \r
+             // Emit URX_LB_START\r
+-            int32_t op = URX_BUILD(URX_LB_START, dataLoc);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++            appendOp(URX_LB_START, dataLoc);\r
+ \r
+             // Emit URX_LB_CONT\r
+-            op = URX_BUILD(URX_LB_CONT, dataLoc);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
+-            fRXPat->fCompiledPat->addElement(0,  *fStatus);    // MinMatchLength.  To be filled later.\r
+-            fRXPat->fCompiledPat->addElement(0,  *fStatus);    // MaxMatchLength.  To be filled later.\r
+-\r
+-            // Emit the NOP\r
+-            op = URX_BUILD(URX_NOP, 0);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++            appendOp(URX_LB_CONT, dataLoc);\r
++            appendOp(URX_RESERVED_OP, 0);    // MinMatchLength.  To be filled later.\r
++            appendOp(URX_RESERVED_OP, 0);    // MaxMatchLength.  To be filled later.\r
++\r
++            // Emit the NOPs\r
++            appendOp(URX_NOP, 0);\r
++            appendOp(URX_NOP, 0);\r
+ \r
+             // On the Parentheses stack, start a new frame and add the postions\r
+@@ -708,22 +681,18 @@\r
+ \r
+             // Allocate data space\r
+-            int32_t dataLoc = fRXPat->fDataSize;\r
+-            fRXPat->fDataSize += 4;\r
++            int32_t dataLoc = allocateData(4);\r
+ \r
+             // Emit URX_LB_START\r
+-            int32_t op = URX_BUILD(URX_LB_START, dataLoc);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++            appendOp(URX_LB_START, dataLoc);\r
+ \r
+             // Emit URX_LBN_CONT\r
+-            op = URX_BUILD(URX_LBN_CONT, dataLoc);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
+-            fRXPat->fCompiledPat->addElement(0,  *fStatus);    // MinMatchLength.  To be filled later.\r
+-            fRXPat->fCompiledPat->addElement(0,  *fStatus);    // MaxMatchLength.  To be filled later.\r
+-            fRXPat->fCompiledPat->addElement(0,  *fStatus);    // Continue Loc.    To be filled later.\r
+-\r
+-            // Emit the NOP\r
+-            op = URX_BUILD(URX_NOP, 0);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++            appendOp(URX_LBN_CONT, dataLoc);\r
++            appendOp(URX_RESERVED_OP, 0);    // MinMatchLength.  To be filled later.\r
++            appendOp(URX_RESERVED_OP, 0);    // MaxMatchLength.  To be filled later.\r
++            appendOp(URX_RESERVED_OP, 0);    // Continue Loc.    To be filled later.\r
++\r
++            // Emit the NOPs\r
++            appendOp(URX_NOP, 0);\r
++            appendOp(URX_NOP, 0);\r
+ \r
+             // On the Parentheses stack, start a new frame and add the postions\r
+@@ -795,10 +764,7 @@\r
+                 if (URX_TYPE(repeatedOp) == URX_SETREF) {\r
+                     // Emit optimized code for [char set]+\r
+-                    int32_t loopOpI = URX_BUILD(URX_LOOP_SR_I, URX_VAL(repeatedOp));\r
+-                    fRXPat->fCompiledPat->addElement(loopOpI, *fStatus);\r
+-                    frameLoc = fRXPat->fFrameSize;\r
+-                    fRXPat->fFrameSize++;\r
+-                    int32_t loopOpC = URX_BUILD(URX_LOOP_C, frameLoc);\r
+-                    fRXPat->fCompiledPat->addElement(loopOpC, *fStatus);\r
++                    appendOp(URX_LOOP_SR_I, URX_VAL(repeatedOp));\r
++                    frameLoc = allocateStackData(1);\r
++                    appendOp(URX_LOOP_C, frameLoc);\r
+                     break;\r
+                 }\r
+@@ -808,5 +774,5 @@\r
+                     URX_TYPE(repeatedOp) == URX_DOTANY_UNIX) {\r
+                     // Emit Optimized code for .+ operations.\r
+-                    int32_t loopOpI = URX_BUILD(URX_LOOP_DOT_I, 0);\r
++                    int32_t loopOpI = buildOp(URX_LOOP_DOT_I, 0);\r
+                     if (URX_TYPE(repeatedOp) == URX_DOTANY_ALL) {\r
+                         // URX_LOOP_DOT_I operand is a flag indicating ". matches any" mode.\r
+@@ -816,9 +782,7 @@\r
+                         loopOpI |= 2;\r
+                     }\r
+-                    fRXPat->fCompiledPat->addElement(loopOpI, *fStatus);\r
+-                    frameLoc = fRXPat->fFrameSize;\r
+-                    fRXPat->fFrameSize++;\r
+-                    int32_t loopOpC = URX_BUILD(URX_LOOP_C, frameLoc);\r
+-                    fRXPat->fCompiledPat->addElement(loopOpC, *fStatus);\r
++                    appendOp(loopOpI);\r
++                    frameLoc = allocateStackData(1);\r
++                    appendOp(URX_LOOP_C, frameLoc);\r
+                     break;\r
+                 }\r
+@@ -834,16 +798,13 @@\r
+                 // Emit the code sequence that can handle it.\r
+                 insertOp(topLoc);\r
+-                frameLoc =  fRXPat->fFrameSize;\r
+-                fRXPat->fFrameSize++;\r
+-\r
+-                int32_t op = URX_BUILD(URX_STO_INP_LOC, frameLoc);\r
++                frameLoc = allocateStackData(1);\r
++\r
++                int32_t op = buildOp(URX_STO_INP_LOC, frameLoc);\r
+                 fRXPat->fCompiledPat->setElementAt(op, topLoc);\r
+ \r
+-                op = URX_BUILD(URX_JMP_SAV_X, topLoc+1);\r
+-                fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++                appendOp(URX_JMP_SAV_X, topLoc+1);\r
+             } else {\r
+                 // Simpler code when the repeated body must match something non-empty\r
+-                int32_t  jmpOp  = URX_BUILD(URX_JMP_SAV, topLoc);\r
+-                fRXPat->fCompiledPat->addElement(jmpOp, *fStatus);\r
++                appendOp(URX_JMP_SAV, topLoc);\r
+             }\r
+         }\r
+@@ -857,6 +818,5 @@\r
+         {\r
+             int32_t topLoc      = blockTopLoc(FALSE);\r
+-            int32_t saveStateOp = URX_BUILD(URX_STATE_SAVE, topLoc);\r
+-            fRXPat->fCompiledPat->addElement(saveStateOp, *fStatus);\r
++            appendOp(URX_STATE_SAVE, topLoc);\r
+         }\r
+         break;\r
+@@ -872,5 +832,5 @@\r
+         {\r
+             int32_t   saveStateLoc = blockTopLoc(TRUE);\r
+-            int32_t   saveStateOp  = URX_BUILD(URX_STATE_SAVE, fRXPat->fCompiledPat->size());\r
++            int32_t   saveStateOp  = buildOp(URX_STATE_SAVE, fRXPat->fCompiledPat->size());\r
+             fRXPat->fCompiledPat->setElementAt(saveStateOp, saveStateLoc);\r
+         }\r
+@@ -891,12 +851,10 @@\r
+             int32_t  jmp2_loc = fRXPat->fCompiledPat->size();\r
+ \r
+-            int32_t  jmp1_op  = URX_BUILD(URX_JMP, jmp2_loc+1);\r
++            int32_t  jmp1_op  = buildOp(URX_JMP, jmp2_loc+1);\r
+             fRXPat->fCompiledPat->setElementAt(jmp1_op, jmp1_loc);\r
+ \r
+-            int32_t  jmp2_op  = URX_BUILD(URX_JMP, jmp2_loc+2);\r
+-            fRXPat->fCompiledPat->addElement(jmp2_op, *fStatus);\r
+-\r
+-            int32_t  save_op  = URX_BUILD(URX_STATE_SAVE, jmp1_loc+1);\r
+-            fRXPat->fCompiledPat->addElement(save_op, *fStatus);\r
++            appendOp(URX_JMP, jmp2_loc+2);\r
++\r
++            appendOp(URX_STATE_SAVE, jmp1_loc+1);\r
+         }\r
+         break;\r
+@@ -938,10 +896,8 @@\r
+                 if (URX_TYPE(repeatedOp) == URX_SETREF) {\r
+                     // Emit optimized code for a [char set]*\r
+-                    int32_t loopOpI = URX_BUILD(URX_LOOP_SR_I, URX_VAL(repeatedOp));\r
++                    int32_t loopOpI = buildOp(URX_LOOP_SR_I, URX_VAL(repeatedOp));\r
+                     fRXPat->fCompiledPat->setElementAt(loopOpI, topLoc);\r
+-                    dataLoc = fRXPat->fFrameSize;\r
+-                    fRXPat->fFrameSize++;\r
+-                    int32_t loopOpC = URX_BUILD(URX_LOOP_C, dataLoc);\r
+-                    fRXPat->fCompiledPat->addElement(loopOpC, *fStatus);\r
++                    dataLoc = allocateStackData(1);\r
++                    appendOp(URX_LOOP_C, dataLoc);\r
+                     break;\r
+                 }\r
+@@ -951,5 +907,5 @@\r
+                     URX_TYPE(repeatedOp) == URX_DOTANY_UNIX) {\r
+                     // Emit Optimized code for .* operations.\r
+-                    int32_t loopOpI = URX_BUILD(URX_LOOP_DOT_I, 0);\r
++                    int32_t loopOpI = buildOp(URX_LOOP_DOT_I, 0);\r
+                     if (URX_TYPE(repeatedOp) == URX_DOTANY_ALL) {\r
+                         // URX_LOOP_DOT_I operand is a flag indicating . matches any mode.\r
+@@ -960,8 +916,6 @@\r
+                     }\r
+                     fRXPat->fCompiledPat->setElementAt(loopOpI, topLoc);\r
+-                    dataLoc = fRXPat->fFrameSize;\r
+-                    fRXPat->fFrameSize++;\r
+-                    int32_t loopOpC = URX_BUILD(URX_LOOP_C, dataLoc);\r
+-                    fRXPat->fCompiledPat->addElement(loopOpC, *fStatus);\r
++                    dataLoc = allocateStackData(1);\r
++                    appendOp(URX_LOOP_C, dataLoc);\r
+                     break;\r
+                 }\r
+@@ -972,5 +926,5 @@\r
+ \r
+             int32_t   saveStateLoc = blockTopLoc(TRUE);\r
+-            int32_t   jmpOp        = URX_BUILD(URX_JMP_SAV, saveStateLoc+1);\r
++            int32_t   jmpOp        = buildOp(URX_JMP_SAV, saveStateLoc+1);\r
+ \r
+             // Check for minimum match length of zero, which requires\r
+@@ -978,10 +932,9 @@\r
+             if (minMatchLength(saveStateLoc, fRXPat->fCompiledPat->size()-1) == 0) {\r
+                 insertOp(saveStateLoc);\r
+-                dataLoc =  fRXPat->fFrameSize;\r
+-                fRXPat->fFrameSize++;\r
+-\r
+-                int32_t op = URX_BUILD(URX_STO_INP_LOC, dataLoc);\r
++                dataLoc = allocateStackData(1);\r
++\r
++                int32_t op = buildOp(URX_STO_INP_LOC, dataLoc);\r
+                 fRXPat->fCompiledPat->setElementAt(op, saveStateLoc+1);\r
+-                jmpOp      = URX_BUILD(URX_JMP_SAV_X, saveStateLoc+2);\r
++                jmpOp      = buildOp(URX_JMP_SAV_X, saveStateLoc+2);\r
+             }\r
+ \r
+@@ -990,10 +943,10 @@\r
+             int32_t continueLoc = fRXPat->fCompiledPat->size()+1;\r
+ \r
+-            // Put together the save state op store it into the compiled code.\r
+-            int32_t saveStateOp = URX_BUILD(URX_STATE_SAVE, continueLoc);\r
++            // Put together the save state op and store it into the compiled code.\r
++            int32_t saveStateOp = buildOp(URX_STATE_SAVE, continueLoc);\r
+             fRXPat->fCompiledPat->setElementAt(saveStateOp, saveStateLoc);\r
+ \r
+             // Append the URX_JMP_SAV or URX_JMPX operation to the compiled pattern.\r
+-            fRXPat->fCompiledPat->addElement(jmpOp, *fStatus);\r
++            appendOp(jmpOp);\r
+         }\r
+         break;\r
+@@ -1009,8 +962,7 @@\r
+             int32_t     jmpLoc  = blockTopLoc(TRUE);                   // loc  1.\r
+             int32_t     saveLoc = fRXPat->fCompiledPat->size();        // loc  3.\r
+-            int32_t     jmpOp   = URX_BUILD(URX_JMP, saveLoc);\r
+-            int32_t     stateSaveOp = URX_BUILD(URX_STATE_SAVE, jmpLoc+1);\r
++            int32_t     jmpOp   = buildOp(URX_JMP, saveLoc);\r
+             fRXPat->fCompiledPat->setElementAt(jmpOp, jmpLoc);\r
+-            fRXPat->fCompiledPat->addElement(stateSaveOp, *fStatus);\r
++            appendOp(URX_STATE_SAVE, jmpLoc+1);\r
+         }\r
+         break;\r
+@@ -1085,7 +1037,7 @@\r
+             // First the STO_SP before the start of the loop\r
+             insertOp(topLoc);\r
+-            int32_t  varLoc    = fRXPat->fDataSize;    // Reserve a data location for saving the\r
+-            fRXPat->fDataSize += 1;                    //  state stack ptr.\r
+-            int32_t  op        = URX_BUILD(URX_STO_SP, varLoc);\r
++\r
++            int32_t  varLoc = allocateData(1);   // Reserve a data location for saving the\r
++            int32_t  op     = buildOp(URX_STO_SP, varLoc);\r
+             fRXPat->fCompiledPat->setElementAt(op, topLoc);\r
+ \r
+@@ -1096,6 +1048,5 @@\r
+ \r
+             // Then the LD_SP after the end of the loop\r
+-            op = URX_BUILD(URX_LD_SP, varLoc);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++            appendOp(URX_LD_SP, varLoc);\r
+         }\r
+ \r
+@@ -1133,13 +1084,11 @@\r
+         {\r
+             fixLiterals(FALSE);\r
+-            int32_t   op;\r
+             if (fModeFlags & UREGEX_DOTALL) {\r
+-                op = URX_BUILD(URX_DOTANY_ALL, 0);\r
++                appendOp(URX_DOTANY_ALL, 0);\r
+             } else if (fModeFlags & UREGEX_UNIX_LINES) {\r
+-                op = URX_BUILD(URX_DOTANY_UNIX, 0);\r
++                appendOp(URX_DOTANY_UNIX, 0);\r
+             } else {\r
+-                op = URX_BUILD(URX_DOTANY, 0);\r
+-            }\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++                appendOp(URX_DOTANY, 0);\r
++            }\r
+         }\r
+         break;\r
+@@ -1148,15 +1097,13 @@\r
+         {\r
+             fixLiterals(FALSE);\r
+-            int32_t op = 0;\r
+             if (       (fModeFlags & UREGEX_MULTILINE) == 0 && (fModeFlags & UREGEX_UNIX_LINES) == 0) {\r
+-                op = URX_CARET;\r
++                appendOp(URX_CARET, 0);\r
+             } else if ((fModeFlags & UREGEX_MULTILINE) != 0 && (fModeFlags & UREGEX_UNIX_LINES) == 0) {\r
+-                op = URX_CARET_M;\r
++                appendOp(URX_CARET_M, 0);\r
+             } else if ((fModeFlags & UREGEX_MULTILINE) == 0 && (fModeFlags & UREGEX_UNIX_LINES) != 0) {\r
+-                op = URX_CARET;   // Only testing true start of input.\r
++                appendOp(URX_CARET, 0);   // Only testing true start of input.\r
+             } else if ((fModeFlags & UREGEX_MULTILINE) != 0 && (fModeFlags & UREGEX_UNIX_LINES) != 0) {\r
+-                op = URX_CARET_M_UNIX;\r
+-            }\r
+-            fRXPat->fCompiledPat->addElement(URX_BUILD(op, 0), *fStatus);\r
++                appendOp(URX_CARET_M_UNIX, 0);\r
++            }\r
+         }\r
+         break;\r
+@@ -1165,15 +1112,13 @@\r
+         {\r
+             fixLiterals(FALSE);\r
+-            int32_t op = 0;\r
+             if (       (fModeFlags & UREGEX_MULTILINE) == 0 && (fModeFlags & UREGEX_UNIX_LINES) == 0) {\r
+-                op = URX_DOLLAR;\r
++                appendOp(URX_DOLLAR, 0);\r
+             } else if ((fModeFlags & UREGEX_MULTILINE) != 0 && (fModeFlags & UREGEX_UNIX_LINES) == 0) {\r
+-                op = URX_DOLLAR_M;\r
++                appendOp(URX_DOLLAR_M, 0);\r
+             } else if ((fModeFlags & UREGEX_MULTILINE) == 0 && (fModeFlags & UREGEX_UNIX_LINES) != 0) {\r
+-                op = URX_DOLLAR_D;\r
++                appendOp(URX_DOLLAR_D, 0);\r
+             } else if ((fModeFlags & UREGEX_MULTILINE) != 0 && (fModeFlags & UREGEX_UNIX_LINES) != 0) {\r
+-                op = URX_DOLLAR_MD;\r
+-            }\r
+-            fRXPat->fCompiledPat->addElement(URX_BUILD(op, 0), *fStatus);\r
++                appendOp(URX_DOLLAR_MD, 0);\r
++            }\r
+         }\r
+         break;\r
+@@ -1181,5 +1126,5 @@\r
+     case doBackslashA:\r
+         fixLiterals(FALSE);\r
+-        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_CARET, 0), *fStatus);\r
++        appendOp(URX_CARET, 0);\r
+         break;\r
+ \r
+@@ -1193,5 +1138,5 @@\r
+             fixLiterals(FALSE);\r
+             int32_t op = (fModeFlags & UREGEX_UWORD)? URX_BACKSLASH_BU : URX_BACKSLASH_B;\r
+-            fRXPat->fCompiledPat->addElement(URX_BUILD(op, 1), *fStatus);\r
++            appendOp(op, 1);\r
+         }\r
+         break;\r
+@@ -1206,5 +1151,5 @@\r
+             fixLiterals(FALSE);\r
+             int32_t op = (fModeFlags & UREGEX_UWORD)? URX_BACKSLASH_BU : URX_BACKSLASH_B;\r
+-            fRXPat->fCompiledPat->addElement(URX_BUILD(op, 0), *fStatus);\r
++            appendOp(op, 0);\r
+         }\r
+         break;\r
+@@ -1212,44 +1157,40 @@\r
+     case doBackslashD:\r
+         fixLiterals(FALSE);\r
+-        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKSLASH_D, 1), *fStatus);\r
++        appendOp(URX_BACKSLASH_D, 1);\r
+         break;\r
+ \r
+     case doBackslashd:\r
+         fixLiterals(FALSE);\r
+-        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKSLASH_D, 0), *fStatus);\r
++        appendOp(URX_BACKSLASH_D, 0);\r
+         break;\r
+ \r
+     case doBackslashG:\r
+         fixLiterals(FALSE);\r
+-        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKSLASH_G, 0), *fStatus);\r
++        appendOp(URX_BACKSLASH_G, 0);\r
+         break;\r
+ \r
+     case doBackslashS:\r
+         fixLiterals(FALSE);\r
+-        fRXPat->fCompiledPat->addElement(\r
+-            URX_BUILD(URX_STAT_SETREF_N, URX_ISSPACE_SET), *fStatus);\r
++        appendOp(URX_STAT_SETREF_N, URX_ISSPACE_SET);\r
+         break;\r
+ \r
+     case doBackslashs:\r
+         fixLiterals(FALSE);\r
+-        fRXPat->fCompiledPat->addElement(\r
+-            URX_BUILD(URX_STATIC_SETREF, URX_ISSPACE_SET), *fStatus);\r
++        appendOp(URX_STATIC_SETREF, URX_ISSPACE_SET);\r
+         break;\r
+ \r
+     case doBackslashW:\r
+         fixLiterals(FALSE);\r
+-        fRXPat->fCompiledPat->addElement(\r
+-            URX_BUILD(URX_STAT_SETREF_N, URX_ISWORD_SET), *fStatus);\r
++        appendOp(URX_STAT_SETREF_N, URX_ISWORD_SET);\r
+         break;\r
+ \r
+     case doBackslashw:\r
+         fixLiterals(FALSE);\r
+-        fRXPat->fCompiledPat->addElement(\r
+-            URX_BUILD(URX_STATIC_SETREF, URX_ISWORD_SET), *fStatus);\r
++        appendOp(URX_STATIC_SETREF, URX_ISWORD_SET);\r
+         break;\r
+ \r
+     case doBackslashX:\r
+         fixLiterals(FALSE);\r
+-        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKSLASH_X, 0), *fStatus);\r
++        appendOp(URX_BACKSLASH_X, 0);\r
+         break;\r
+ \r
+@@ -1257,10 +1198,10 @@\r
+     case doBackslashZ:\r
+         fixLiterals(FALSE);\r
+-        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_DOLLAR, 0), *fStatus);\r
++        appendOp(URX_DOLLAR, 0);\r
+         break;\r
+ \r
+     case doBackslashz:\r
+         fixLiterals(FALSE);\r
+-        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKSLASH_Z, 0), *fStatus);\r
++        appendOp(URX_BACKSLASH_Z, 0);\r
+         break;\r
+ \r
+@@ -1322,11 +1263,9 @@\r
+                                      //    and shouldn't enter this code path at all.\r
+             fixLiterals(FALSE);\r
+-            int32_t  op;\r
+             if (fModeFlags & UREGEX_CASE_INSENSITIVE) {\r
+-                op = URX_BUILD(URX_BACKREF_I, groupNum);\r
++                appendOp(URX_BACKREF_I, groupNum);\r
+             } else {\r
+-                op = URX_BUILD(URX_BACKREF, groupNum);\r
+-            }\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++                appendOp(URX_BACKREF, groupNum);\r
++            }\r
+         }\r
+         break;\r
+@@ -1349,20 +1288,16 @@\r
+             // Emit the STO_SP\r
+             int32_t   topLoc = blockTopLoc(TRUE);\r
+-            int32_t   stoLoc = fRXPat->fDataSize;\r
+-            fRXPat->fDataSize++;       // Reserve the data location for storing save stack ptr.\r
+-            int32_t   op     = URX_BUILD(URX_STO_SP, stoLoc);\r
++            int32_t   stoLoc = allocateData(1);  // Reserve the data location for storing save stack ptr.\r
++            int32_t   op     = buildOp(URX_STO_SP, stoLoc);\r
+             fRXPat->fCompiledPat->setElementAt(op, topLoc);\r
+ \r
+             // Emit the STATE_SAVE\r
+-            op = URX_BUILD(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+2);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++            appendOp(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+2);\r
+ \r
+             // Emit the JMP\r
+-            op = URX_BUILD(URX_JMP, topLoc+1);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++            appendOp(URX_JMP, topLoc+1);\r
+ \r
+             // Emit the LD_SP\r
+-            op = URX_BUILD(URX_LD_SP, stoLoc);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++            appendOp(URX_LD_SP, stoLoc);\r
+         }\r
+         break;\r
+@@ -1384,21 +1319,18 @@\r
+ \r
+             // emit   STO_SP     loc\r
+-            int32_t   stoLoc = fRXPat->fDataSize;\r
+-            fRXPat->fDataSize++;       // Reserve the data location for storing save stack ptr.\r
+-            int32_t   op     = URX_BUILD(URX_STO_SP, stoLoc);\r
++            int32_t   stoLoc = allocateData(1);    // Reserve the data location for storing save stack ptr.\r
++            int32_t   op     = buildOp(URX_STO_SP, stoLoc);\r
+             fRXPat->fCompiledPat->setElementAt(op, topLoc);\r
+ \r
+             // Emit the SAVE_STATE   5\r
+             int32_t L7 = fRXPat->fCompiledPat->size()+1;\r
+-            op = URX_BUILD(URX_STATE_SAVE, L7);\r
++            op = buildOp(URX_STATE_SAVE, L7);\r
+             fRXPat->fCompiledPat->setElementAt(op, topLoc+1);\r
+ \r
+             // Append the JMP operation.\r
+-            op = URX_BUILD(URX_JMP, topLoc+1);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++            appendOp(URX_JMP, topLoc+1);\r
+ \r
+             // Emit the LD_SP       loc\r
+-            op = URX_BUILD(URX_LD_SP, stoLoc);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++            appendOp(URX_LD_SP, stoLoc);\r
+         }\r
+         break;\r
+@@ -1419,17 +1351,15 @@\r
+ \r
+             // Emit the STO_SP\r
+-            int32_t   stoLoc = fRXPat->fDataSize;\r
+-            fRXPat->fDataSize++;       // Reserve the data location for storing save stack ptr.\r
+-            int32_t   op     = URX_BUILD(URX_STO_SP, stoLoc);\r
++            int32_t   stoLoc = allocateData(1);   // Reserve the data location for storing save stack ptr.\r
++            int32_t   op     = buildOp(URX_STO_SP, stoLoc);\r
+             fRXPat->fCompiledPat->setElementAt(op, topLoc);\r
+ \r
+             // Emit the SAVE_STATE\r
+             int32_t   continueLoc = fRXPat->fCompiledPat->size()+1;\r
+-            op = URX_BUILD(URX_STATE_SAVE, continueLoc);\r
++            op = buildOp(URX_STATE_SAVE, continueLoc);\r
+             fRXPat->fCompiledPat->setElementAt(op, topLoc+1);\r
+ \r
+             // Emit the LD_SP\r
+-            op = URX_BUILD(URX_LD_SP, stoLoc);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++            appendOp(URX_LD_SP, stoLoc);\r
+         }\r
+         break;\r
+@@ -1488,6 +1418,6 @@\r
+         {\r
+             fixLiterals(FALSE);\r
+-            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);\r
+-            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);\r
++            appendOp(URX_NOP, 0);\r
++            appendOp(URX_NOP, 0);\r
+ \r
+             // On the Parentheses stack, start a new frame and add the postions\r
+@@ -1826,5 +1756,4 @@\r
+ //------------------------------------------------------------------------------\r
+ void    RegexCompile::fixLiterals(UBool split) {\r
+-    int32_t  op = 0;                       // An op from/for the compiled pattern.\r
+ \r
+     // If no literal characters have been scanned but not yet had code generated\r
+@@ -1865,21 +1794,21 @@\r
+         if ((fModeFlags & UREGEX_CASE_INSENSITIVE) &&\r
+                  u_hasBinaryProperty(lastCodePoint, UCHAR_CASE_SENSITIVE)) {\r
+-            op = URX_BUILD(URX_ONECHAR_I, lastCodePoint);\r
++            appendOp(URX_ONECHAR_I, lastCodePoint);\r
+         } else {\r
+-            op = URX_BUILD(URX_ONECHAR, lastCodePoint);\r
+-        }\r
+-        fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++            appendOp(URX_ONECHAR, lastCodePoint);\r
++        }\r
+     } else {\r
+         // Two or more chars, emit a URX_STRING to match them.\r
++        if (fLiteralChars.length() > 0x00ffffff || fRXPat->fLiteralText.length() > 0x00ffffff) {\r
++            error(U_REGEX_PATTERN_TOO_BIG);\r
++        }\r
+         if (fModeFlags & UREGEX_CASE_INSENSITIVE) {\r
+-            op = URX_BUILD(URX_STRING_I, fRXPat->fLiteralText.length());\r
++            appendOp(URX_STRING_I, fRXPat->fLiteralText.length());\r
+         } else {\r
+             // TODO here:  add optimization to split case sensitive strings of length two\r
+             //             into two single char ops, for efficiency.\r
+-            op = URX_BUILD(URX_STRING, fRXPat->fLiteralText.length());\r
+-        }\r
+-        fRXPat->fCompiledPat->addElement(op, *fStatus);\r
+-        op = URX_BUILD(URX_STRING_LEN, fLiteralChars.length());\r
+-        fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++            appendOp(URX_STRING, fRXPat->fLiteralText.length());\r
++        }\r
++        appendOp(URX_STRING_LEN, fLiteralChars.length());\r
+ \r
+         // Add this string into the accumulated strings of the compiled pattern.\r
+@@ -1891,6 +1820,56 @@\r
+ \r
+ \r
+-\r
+-\r
++int32_t RegexCompile::buildOp(int32_t type, int32_t val) {\r
++    if (U_FAILURE(*fStatus)) {\r
++        return 0;\r
++    }\r
++    if (type < 0 || type > 255) {\r
++        U_ASSERT(FALSE);\r
++        error(U_REGEX_INTERNAL_ERROR);\r
++        type = URX_RESERVED_OP;\r
++    }\r
++    if (val > 0x00ffffff) {\r
++        U_ASSERT(FALSE);\r
++        error(U_REGEX_INTERNAL_ERROR);\r
++        val = 0;\r
++    }\r
++    if (val < 0) {\r
++        if (!(type == URX_RESERVED_OP_N || type == URX_RESERVED_OP)) {\r
++            U_ASSERT(FALSE);\r
++            error(U_REGEX_INTERNAL_ERROR);\r
++            return -1;\r
++        }\r
++        if (URX_TYPE(val) != 0xff) {\r
++            U_ASSERT(FALSE);\r
++            error(U_REGEX_INTERNAL_ERROR);\r
++            return -1;\r
++        }\r
++        type = URX_RESERVED_OP_N;\r
++    }\r
++    return (type << 24) | val;\r
++}\r
++\r
++\r
++//------------------------------------------------------------------------------\r
++//\r
++//   appendOp()             Append a new instruction onto the compiled pattern\r
++//                          Includes error checking, limiting the size of the\r
++//                          pattern to lengths that can be represented in the\r
++//                          24 bit operand field of an instruction.\r
++//\r
++//------------------------------------------------------------------------------\r
++void RegexCompile::appendOp(int32_t op) {\r
++    if (U_FAILURE(*fStatus)) {\r
++        return;\r
++    }\r
++    fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++    if ((fRXPat->fCompiledPat->size() > 0x00fffff0) && U_SUCCESS(*fStatus)) {\r
++        error(U_REGEX_PATTERN_TOO_BIG);\r
++    }\r
++}\r
++\r
++void RegexCompile::appendOp(int32_t type, int32_t val) {\r
++    appendOp(buildOp(type, val));\r
++}\r
+ \r
+ \r
+@@ -1908,5 +1887,5 @@\r
+     U_ASSERT(where>0 && where < code->size());\r
+ \r
+-    int32_t  nop = URX_BUILD(URX_NOP, 0);\r
++    int32_t  nop = buildOp(URX_NOP, 0);\r
+     code->insertElementAt(nop, where, *fStatus);\r
+ \r
+@@ -1929,5 +1908,5 @@\r
+             //   needs to be incremented to adjust for the insertion.\r
+             opValue++;\r
+-            op = URX_BUILD(opType, opValue);\r
++            op = buildOp(opType, opValue);\r
+             code->setElementAt(op, loc);\r
+         }\r
+@@ -1953,4 +1932,56 @@\r
+ }\r
+ \r
++\r
++//------------------------------------------------------------------------------\r
++//\r
++//   allocateData()        Allocate storage in the matcher's static data area.\r
++//                         Return the index for the newly allocated data.\r
++//                         The storage won't actually exist until we are running a match\r
++//                         operation, but the storage indexes are inserted into various\r
++//                         opcodes while compiling the pattern.\r
++//\r
++//------------------------------------------------------------------------------\r
++int32_t RegexCompile::allocateData(int32_t size) {\r
++    if (U_FAILURE(*fStatus)) {\r
++        return 0;\r
++    }\r
++    if (size <= 0 || size > 0x100 || fRXPat->fDataSize < 0) {\r
++        error(U_REGEX_INTERNAL_ERROR);\r
++        return 0;\r
++    }\r
++    int32_t dataIndex = fRXPat->fDataSize;\r
++    fRXPat->fDataSize += size;\r
++    if (fRXPat->fDataSize >= 0x00fffff0) {\r
++        error(U_REGEX_INTERNAL_ERROR);\r
++    }\r
++    return dataIndex;\r
++}\r
++\r
++\r
++//------------------------------------------------------------------------------\r
++//\r
++//   allocateStackData()   Allocate space in the back-tracking stack frame.\r
++//                         Return the index for the newly allocated data.\r
++//                         The frame indexes are inserted into various\r
++//                         opcodes while compiling the pattern, meaning that frame\r
++//                         size must be restricted to the size that will fit\r
++//                         as an operand (24 bits).\r
++//\r
++//------------------------------------------------------------------------------\r
++int32_t RegexCompile::allocateStackData(int32_t size) {\r
++    if (U_FAILURE(*fStatus)) {\r
++        return 0;\r
++    }\r
++    if (size <= 0 || size > 0x100 || fRXPat->fFrameSize < 0) {\r
++        error(U_REGEX_INTERNAL_ERROR);\r
++        return 0;\r
++    }\r
++    int32_t dataIndex = fRXPat->fFrameSize;\r
++    fRXPat->fFrameSize += size;\r
++    if (fRXPat->fFrameSize >= 0x00fffff0) {\r
++        error(U_REGEX_PATTERN_TOO_BIG);\r
++    }\r
++    return dataIndex;\r
++}\r
+ \r
+ \r
+@@ -1996,5 +2027,5 @@\r
+         }\r
+         if (reserveLoc) {\r
+-            int32_t  nop = URX_BUILD(URX_NOP, 0);\r
++            int32_t  nop = buildOp(URX_NOP, 0);\r
+             fRXPat->fCompiledPat->insertElementAt(nop, theLoc, *fStatus);\r
+         }\r
+@@ -2071,6 +2102,5 @@\r
+ \r
+             int32_t   frameVarLocation = URX_VAL(captureOp);\r
+-            int32_t   endCaptureOp = URX_BUILD(URX_END_CAPTURE, frameVarLocation);\r
+-            fRXPat->fCompiledPat->addElement(endCaptureOp, *fStatus);\r
++            appendOp(URX_END_CAPTURE, frameVarLocation);\r
+         }\r
+         break;\r
+@@ -2083,6 +2113,5 @@\r
+             U_ASSERT(URX_TYPE(stoOp) == URX_STO_SP);\r
+             int32_t   stoLoc = URX_VAL(stoOp);\r
+-            int32_t   ldOp   = URX_BUILD(URX_LD_SP, stoLoc);\r
+-            fRXPat->fCompiledPat->addElement(ldOp, *fStatus);\r
++            appendOp(URX_LD_SP, stoLoc);\r
+         }\r
+         break;\r
+@@ -2093,6 +2122,5 @@\r
+             U_ASSERT(URX_TYPE(startOp) == URX_LA_START);\r
+             int32_t dataLoc  = URX_VAL(startOp);\r
+-            int32_t op       = URX_BUILD(URX_LA_END, dataLoc);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++            appendOp(URX_LA_END, dataLoc);\r
+         }\r
+         break;\r
+@@ -2104,10 +2132,7 @@\r
+             U_ASSERT(URX_TYPE(startOp) == URX_LA_START);\r
+             int32_t dataLoc  = URX_VAL(startOp);\r
+-            int32_t op       = URX_BUILD(URX_LA_END, dataLoc);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
+-            op               = URX_BUILD(URX_BACKTRACK, 0);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
+-            op               = URX_BUILD(URX_LA_END, dataLoc);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++            appendOp(URX_LA_END, dataLoc);\r
++            appendOp(URX_BACKTRACK, 0);\r
++            appendOp(URX_LA_END, dataLoc);\r
+ \r
+             // Patch the URX_SAVE near the top of the block.\r
+@@ -2116,5 +2141,5 @@\r
+             U_ASSERT(URX_TYPE(saveOp) == URX_STATE_SAVE);\r
+             int32_t dest     = fRXPat->fCompiledPat->size()-1;\r
+-            saveOp           = URX_BUILD(URX_STATE_SAVE, dest);\r
++            saveOp           = buildOp(URX_STATE_SAVE, dest);\r
+             fRXPat->fCompiledPat->setElementAt(saveOp, fMatchOpenParen);\r
+         }\r
+@@ -2129,8 +2154,6 @@\r
+             U_ASSERT(URX_TYPE(startOp) == URX_LB_START);\r
+             int32_t dataLoc  = URX_VAL(startOp);\r
+-            int32_t op       = URX_BUILD(URX_LB_END, dataLoc);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
+-                    op       = URX_BUILD(URX_LA_END, dataLoc);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++            appendOp(URX_LB_END, dataLoc);\r
++            appendOp(URX_LA_END, dataLoc);\r
+ \r
+             // Determine the min and max bounds for the length of the\r
+@@ -2168,6 +2191,5 @@\r
+             U_ASSERT(URX_TYPE(startOp) == URX_LB_START);\r
+             int32_t dataLoc  = URX_VAL(startOp);\r
+-            int32_t op       = URX_BUILD(URX_LBN_END, dataLoc);\r
+-            fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++            appendOp(URX_LBN_END, dataLoc);\r
+ \r
+             // Determine the min and max bounds for the length of the\r
+@@ -2194,5 +2216,5 @@\r
+             // Insert the pattern location to continue at after a successful match\r
+             //  as the last operand of the URX_LBN_CONT\r
+-            op = URX_BUILD(URX_RELOC_OPRND, fRXPat->fCompiledPat->size());\r
++            int32_t op = buildOp(URX_RELOC_OPRND, fRXPat->fCompiledPat->size());\r
+             fRXPat->fCompiledPat->setElementAt(op,  fMatchOpenParen-1);\r
+         }\r
+@@ -2235,5 +2257,5 @@\r
+         {\r
+             // Set of no elements.   Always fails to match.\r
+-            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKTRACK, 0), *fStatus);\r
++            appendOp(URX_BACKTRACK, 0);\r
+             delete theSet;\r
+         }\r
+@@ -2256,6 +2278,5 @@\r
+             int32_t setNumber = fRXPat->fSets->size();\r
+             fRXPat->fSets->addElement(theSet, *fStatus);\r
+-            int32_t setOp = URX_BUILD(URX_SETREF, setNumber);\r
+-            fRXPat->fCompiledPat->addElement(setOp, *fStatus);\r
++            appendOp(URX_SETREF, setNumber);\r
+         }\r
+     }\r
+@@ -2296,11 +2317,8 @@\r
+     //               +1    -->  Input index (for breaking non-progressing loops)\r
+     //                          (Only present if unbounded upper limit on loop)\r
+-    int32_t   counterLoc = fRXPat->fFrameSize;\r
+-    fRXPat->fFrameSize++;\r
+-    if (fIntervalUpper < 0) {\r
+-        fRXPat->fFrameSize++;\r
+-    }\r
+-\r
+-    int32_t   op = URX_BUILD(InitOp, counterLoc);\r
++    int32_t   dataSize = fIntervalUpper < 0 ? 2 : 1;\r
++    int32_t   counterLoc = allocateStackData(dataSize);\r
++\r
++    int32_t   op = buildOp(InitOp, counterLoc);\r
+     fRXPat->fCompiledPat->setElementAt(op, topOfBlock);\r
+ \r
+@@ -2310,5 +2328,5 @@\r
+     //   position to move.\r
+     int32_t loopEnd = fRXPat->fCompiledPat->size();\r
+-    op = URX_BUILD(URX_RELOC_OPRND, loopEnd);\r
++    op = buildOp(URX_RELOC_OPRND, loopEnd);\r
+     fRXPat->fCompiledPat->setElementAt(op, topOfBlock+1);\r
+ \r
+@@ -2319,6 +2337,5 @@\r
+     // Apend the CTR_LOOP op.  The operand is the location of the CTR_INIT op.\r
+     //   Goes at end of the block being looped over, so just append to the code so far.\r
+-    op = URX_BUILD(LoopOp, topOfBlock);\r
+-    fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++    appendOp(LoopOp, topOfBlock);\r
+ \r
+     if ((fIntervalLow & 0xff000000) != 0 ||\r
+@@ -2373,5 +2390,5 @@\r
+     int32_t endOfSequenceLoc = fRXPat->fCompiledPat->size()-1\r
+                                 + fIntervalUpper + (fIntervalUpper-fIntervalLow);\r
+-    int32_t saveOp = URX_BUILD(URX_STATE_SAVE, endOfSequenceLoc);\r
++    int32_t saveOp = buildOp(URX_STATE_SAVE, endOfSequenceLoc);\r
+     if (fIntervalLow == 0) {\r
+         insertOp(topOfBlock);\r
+@@ -2386,11 +2403,8 @@\r
+     int32_t i;\r
+     for (i=1; i<fIntervalUpper; i++ ) {\r
+-        if (i == fIntervalLow) {\r
+-            fRXPat->fCompiledPat->addElement(saveOp, *fStatus);\r
+-        }\r
+-        if (i > fIntervalLow) {\r
+-            fRXPat->fCompiledPat->addElement(saveOp, *fStatus);\r
+-        }\r
+-        fRXPat->fCompiledPat->addElement(op, *fStatus);\r
++        if (i >= fIntervalLow) {\r
++            appendOp(saveOp);\r
++        }\r
++        appendOp(op);\r
+     }\r
+     return TRUE;\r
+@@ -3612,5 +3626,5 @@\r
+                 U_ASSERT(operandAddress>=0 && operandAddress<deltas.size());\r
+                 int32_t fixedOperandAddress = operandAddress - deltas.elementAti(operandAddress);\r
+-                op = URX_BUILD(opType, fixedOperandAddress);\r
++                op = buildOp(opType, fixedOperandAddress);\r
+                 fRXPat->fCompiledPat->setElementAt(op, dst);\r
+                 dst++;\r
+@@ -3627,5 +3641,5 @@\r
+                 }\r
+                 where = fRXPat->fGroupMap->elementAti(where-1);\r
+-                op    = URX_BUILD(opType, where);\r
++                op    = buildOp(opType, where);\r
+                 fRXPat->fCompiledPat->setElementAt(op, dst);\r
+                 dst++;\r
+@@ -3979,5 +3993,5 @@\r
+ //\r
+ //  scanNamedChar\r
+- //            Get a UChar32 from a \N{UNICODE CHARACTER NAME} in the pattern.\r
++//            Get a UChar32 from a \N{UNICODE CHARACTER NAME} in the pattern.\r
+ //\r
+ //             The scan position will be at the 'N'.  On return\r
+Index: /icu/trunk/source/i18n/regexcmp.h\r
+===================================================================\r
+--- /icu/trunk/source/i18n/regexcmp.h  (revision 36800)\r
++++ /icu/trunk/source/i18n/regexcmp.h  (revision 36801)\r
+@@ -105,4 +105,11 @@\r
+     void        insertOp(int32_t where);             // Open up a slot for a new op in the\r
+                                                      //   generated code at the specified location.\r
++    void        appendOp(int32_t op);                // Append a new op to the compiled pattern.\r
++    void        appendOp(int32_t type, int32_t val); // Build & append a new op to the compiled pattern.\r
++    int32_t     buildOp(int32_t type, int32_t val);  // Construct a new pcode instruction.\r
++    int32_t     allocateData(int32_t size);          // Allocate space in the matcher data area.\r
++                                                     //   Return index of the newly allocated data.\r
++    int32_t     allocateStackData(int32_t size);     // Allocate space in the match back-track stack frame.\r
++                                                     //   Return offset index in the frame.\r
+     int32_t     minMatchLength(int32_t start,\r
+                                int32_t end);\r
+Index: /icu/trunk/source/i18n/regeximp.h\r
+===================================================================\r
+--- /icu/trunk/source/i18n/regeximp.h  (revision 36800)\r
++++ /icu/trunk/source/i18n/regeximp.h  (revision 36801)\r
+@@ -1,4 +1,4 @@\r
+ //\r
+-//   Copyright (C) 2002-2013 International Business Machines Corporation\r
++//   Copyright (C) 2002-2014 International Business Machines Corporation\r
+ //   and others. All rights reserved.\r
+ //\r
+@@ -242,5 +242,4 @@\r
+ //  Convenience macros for assembling and disassembling a compiled operation.\r
+ //\r
+-#define URX_BUILD(type, val) (int32_t)((type << 24) | (val))\r
+ #define URX_TYPE(x)          ((uint32_t)(x) >> 24)\r
+ #define URX_VAL(x)           ((x) & 0xffffff)\r
+Index: /icu/trunk/source/test/intltest/regextst.cpp\r
+===================================================================\r
+--- /icu/trunk/source/test/intltest/regextst.cpp       (revision 36800)\r
++++ /icu/trunk/source/test/intltest/regextst.cpp       (revision 36801)\r
+@@ -145,4 +145,7 @@\r
+             if (exec) TestBug11049();\r
+             break;\r
++        case 25: name = "TestBug11371";\r
++            if (exec) TestBug11371();\r
++            break;\r
+         default: name = "";\r
+             break; //needed to end loop\r
+@@ -5368,4 +5371,47 @@\r
+ \r
+ \r
++void RegexTest::TestBug11371() {\r
++    if (quick) {\r
++        logln("Skipping test. Runs in exhuastive mode only.");\r
++        return;\r
++    }\r
++    UErrorCode status = U_ZERO_ERROR;\r
++    UnicodeString patternString;\r
++\r
++    for (int i=0; i<8000000; i++) {\r
++        patternString.append(UnicodeString("()"));\r
++    }\r
++    LocalPointer<RegexPattern> compiledPat(RegexPattern::compile(patternString, 0, status));\r
++    if (status != U_REGEX_PATTERN_TOO_BIG) {\r
++        errln("File %s, line %d expected status=U_REGEX_PATTERN_TOO_BIG; got %s.",\r
++              __FILE__, __LINE__, u_errorName(status));\r
++    }\r
++\r
++    status = U_ZERO_ERROR;\r
++    patternString = "(";\r
++    for (int i=0; i<20000000; i++) {\r
++        patternString.append(UnicodeString("A++"));\r
++    }\r
++    patternString.append(UnicodeString("){0}B++"));\r
++    LocalPointer<RegexPattern> compiledPat2(RegexPattern::compile(patternString, 0, status));\r
++    if (status != U_REGEX_PATTERN_TOO_BIG) {\r
++        errln("File %s, line %d expected status=U_REGEX_PATTERN_TOO_BIG; got %s.",\r
++              __FILE__, __LINE__, u_errorName(status));\r
++    }\r
++\r
++    // Pattern with too much string data, such that string indexes overflow operand data field size\r
++    // in compiled instruction.\r
++    status = U_ZERO_ERROR;\r
++    patternString = "";\r
++    while (patternString.length() < 0x00ffffff) {\r
++        patternString.append(UnicodeString("stuff and things dont you know, these are a few of my favorite strings\n"));\r
++    }\r
++    patternString.append(UnicodeString("X? trailing string"));\r
++    LocalPointer<RegexPattern> compiledPat3(RegexPattern::compile(patternString, 0, status));\r
++    if (status != U_REGEX_PATTERN_TOO_BIG) {\r
++        errln("File %s, line %d expected status=U_REGEX_PATTERN_TOO_BIG; got %s.",\r
++              __FILE__, __LINE__, u_errorName(status));\r
++    }\r
++}\r
+ \r
+ #endif  /* !UCONFIG_NO_REGULAR_EXPRESSIONS  */\r
+Index: /icu/trunk/source/test/intltest/regextst.h\r
+===================================================================\r
+--- /icu/trunk/source/test/intltest/regextst.h (revision 36800)\r
++++ /icu/trunk/source/test/intltest/regextst.h (revision 36801)\r
+@@ -51,4 +51,5 @@\r
+     virtual void TestCaseInsensitiveStarters();\r
+     virtual void TestBug11049();\r
++    virtual void TestBug11371();\r
+     \r
+     // The following functions are internal to the regexp tests.\r
similarity index 94%
rename from dev-libs/icu/icu-53.1-r1.ebuild
rename to dev-libs/icu/icu-53.1-r3.ebuild
index 27081c30b5a7ad23446d665ae49e19c6bfa7951f..d6ab791a832415da3d9026cd557a37f5235280b3 100644 (file)
@@ -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 (file)
index 0000000..8455ee9
--- /dev/null
@@ -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
+}