Skip to content

Commit b41e90c

Browse files
authored
Fix bug #81481 (xml_get_current_byte_index limited to 32-bit numbers on 64-bit builds) (php#14845)
The return value is long in both expat and expat2 (with XML_LARGE_SIZE not set).
1 parent ec19abf commit b41e90c

File tree

5 files changed

+50
-6
lines changed

5 files changed

+50
-6
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ PHP NEWS
1212
. Fixed bug GH-14792 (Compilation failure on pdo_* extensions).
1313
(Peter Kokot)
1414

15+
- XML:
16+
. Fixed bug #81481 (xml_get_current_byte_index limited to 32-bit numbers on
17+
64-bit builds). (nielsdos)
18+
1519
04 Jul 2024, PHP 8.4.0alpha1
1620

1721
- BCMath:

UPGRADING.INTERNALS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,11 @@ PHP 8.4 INTERNALS UPGRADE NOTES
292292
- The ext/session/php_session.h doesn't transitively include the
293293
ext/hash/php_hash.h header anymore.
294294

295+
i. ext/xml
296+
- Made the expat compatibility wrapper XML_GetCurrentByteIndex return a long
297+
instead of an int. This corresponds to the XML_Index type when
298+
XML_LARGE_SIZE is not used in expat.
299+
295300
========================
296301
4. OpCode changes
297302
========================

ext/xml/compat.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,7 @@ XML_GetCurrentColumnNumber(XML_Parser parser)
686686
return parser->parser->input->col;
687687
}
688688

689-
PHP_XML_API int
689+
PHP_XML_API long
690690
XML_GetCurrentByteIndex(XML_Parser parser)
691691
{
692692
/* We have to temporarily disable the encoder to satisfy the note from the manual:
@@ -702,16 +702,15 @@ XML_GetCurrentByteIndex(XML_Parser parser)
702702
if (encoder) {
703703
input->buf->encoder = encoder;
704704
}
705-
/* TODO: at one point this should return long probably to make sure that files greater than 2 GiB are handled correctly. */
706-
return (int) result;
705+
return result;
707706
}
708707

709708
PHP_XML_API int
710709
XML_GetCurrentByteCount(XML_Parser parser)
711710
{
712-
/* WARNING: this is identical to ByteIndex; it should probably
711+
/* TODO: this is identical to ByteIndex; it should probably
713712
* be different */
714-
return XML_GetCurrentByteIndex(parser);
713+
return (int) XML_GetCurrentByteIndex(parser);
715714
}
716715

717716
PHP_XML_API const XML_Char *XML_ExpatVersion(void)

ext/xml/expat_compat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ PHP_XML_API int XML_GetErrorCode(XML_Parser);
144144
PHP_XML_API const XML_Char *XML_ErrorString(int);
145145
PHP_XML_API int XML_GetCurrentLineNumber(XML_Parser);
146146
PHP_XML_API int XML_GetCurrentColumnNumber(XML_Parser);
147-
PHP_XML_API int XML_GetCurrentByteIndex(XML_Parser);
147+
PHP_XML_API long XML_GetCurrentByteIndex(XML_Parser);
148148
PHP_XML_API int XML_GetCurrentByteCount(XML_Parser);
149149
PHP_XML_API const XML_Char *XML_ExpatVersion(void);
150150
PHP_XML_API void XML_ParserFree(XML_Parser);

ext/xml/tests/bug81481.phpt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
Bug #81481 (xml_get_current_byte_index limited to 32-bit numbers on 64-bit builds)
3+
--CREDITS--
4+
dev at b65sol dot com
5+
--EXTENSIONS--
6+
xml
7+
--INI--
8+
memory_limit=-1
9+
--SKIPIF--
10+
<?php
11+
require __DIR__ . '/libxml_expat_skipif.inc';
12+
skipif(want_expat: false);
13+
if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
14+
if (PHP_INT_SIZE != 8) die("skip 64-bit only");
15+
if (PHP_OS_FAMILY == 'Windows') die('skip not for Windows');
16+
?>
17+
--FILE--
18+
<?php
19+
$parser = xml_parser_create('UTF-8');
20+
xml_set_element_handler( $parser, 'startelement', null );
21+
22+
$emptylong = str_repeat(' ', 1024*1024);
23+
xml_parse($parser, '<root><i></i><b/><ext>Hello</ext>', false);
24+
for($i = 0; $i < 2200; $i++) {
25+
xml_parse($parser, $emptylong, false);
26+
}
27+
xml_parse($parser, '<ext></ext><ext></ext></root>', false);
28+
29+
function startelement($parser, $name, $attribute) {
30+
if ( $name == 'EXT' ) { echo "Byte Index:", xml_get_current_byte_index($parser), "\n"; }
31+
}
32+
?>
33+
--EXPECT--
34+
Byte Index:21
35+
Byte Index:2306867237
36+
Byte Index:2306867248

0 commit comments

Comments
 (0)