View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0014014 | mantisbt | filters | public | 2012-03-07 08:49 | 2016-11-15 11:43 |
Reporter | schoppi71 | Assigned To | dregad | ||
Priority | normal | Severity | major | Reproducibility | always |
Status | closed | Resolution | fixed | ||
Platform | Linux SuSE Linux Enterprise Serv | OS | SuSe Linux Enterprise Server | OS Version | 10 SP2 64-Bit |
Product Version | 1.2.0 | ||||
Target Version | 1.2.10 | Fixed in Version | 1.2.10 | ||
Summary | 0014014: Search with number > 2147483647 fails on 64-bit systems with PostgreSQL | ||||
Description | I have the same problem and I can reproduce it. I'm using Mantis 1.2.8 with PostgreSQL-DB 8.3.7 on Linux SuSE Linux Enterprise Server 10 SP2 64-Bit. Same problem like 0012880. Errormessage: | ||||
Tags | No tags attached. | ||||
Attached Files | 14014.patch (643 bytes)
diff --git a/core/filter_api.php b/core/filter_api.php index f8de0f8..4fe2f2e 100644 --- a/core/filter_api.php +++ b/core/filter_api.php @@ -1956,7 +1956,7 @@ function filter_get_bug_rows( &$p_page_number, &$p_per_page, &$p_page_count, &$p $t_where_params[] = $c_search; $t_where_params[] = $c_search; - if( is_numeric( $t_search_term ) ) { + if( is_numeric( $t_search_term ) && $t_search_term > 0 && $t_search_term <= 0x7FFFFFFF ) { $c_search_int = (int) $t_search_term; $t_textsearch_where_clause .= " OR $t_bug_table.id = " . db_param(); $t_textsearch_where_clause .= " OR $t_bugnote_table.id = " . db_param(); 14014-2.patch (886 bytes)
diff --git a/core/filter_api.php b/core/filter_api.php index f8de0f8..75f0dc2 100644 --- a/core/filter_api.php +++ b/core/filter_api.php @@ -1956,7 +1956,14 @@ function filter_get_bug_rows( &$p_page_number, &$p_per_page, &$p_page_count, &$p $t_where_params[] = $c_search; $t_where_params[] = $c_search; - if( is_numeric( $t_search_term ) ) { + // PostgreSQL on 64-bit OS hack (see #14014) + if( PHP_INT_MAX > 0x7FFFFFFF && db_is_pgsql() ) { + $t_search_max = 0x7FFFFFFF; + } else { + $t_search_max = PHP_INT_MAX; + } + // Note: no need to test negative values, '-' sign is removed above + if( is_numeric( $t_search_term ) && $t_search_term <= $t_search_max ) { $c_search_int = (int) $t_search_term; $t_textsearch_where_clause .= " OR $t_bug_table.id = " . db_param(); $t_textsearch_where_clause .= " OR $t_bugnote_table.id = " . db_param(); 14014-3.patch (1,243 bytes)
diff --git a/core/filter_api.php b/core/filter_api.php index f8de0f8..b9bd6eb 100644 --- a/core/filter_api.php +++ b/core/filter_api.php @@ -1957,11 +1957,20 @@ function filter_get_bug_rows( &$p_page_number, &$p_per_page, &$p_page_count, &$p $t_where_params[] = $c_search; if( is_numeric( $t_search_term ) ) { - $c_search_int = (int) $t_search_term; - $t_textsearch_where_clause .= " OR $t_bug_table.id = " . db_param(); - $t_textsearch_where_clause .= " OR $t_bugnote_table.id = " . db_param(); - $t_where_params[] = $c_search_int; - $t_where_params[] = $c_search_int; + // PostgreSQL on 64-bit OS hack (see #14014) + if( PHP_INT_MAX > 0x7FFFFFFF && db_is_pgsql() ) { + $t_search_max = 0x7FFFFFFF; + } else { + $t_search_max = PHP_INT_MAX; + } + // Note: no need to test negative values, '-' sign is removed above + if( $t_search_term <= $t_search_max ) { + $c_search_int = (int) $t_search_term; + $t_textsearch_where_clause .= " OR $t_bug_table.id = " . db_param(); + $t_textsearch_where_clause .= " OR $t_bugnote_table.id = " . db_param(); + $t_where_params[] = $c_search_int; + $t_where_params[] = $c_search_int; + } } $t_textsearch_where_clause .= ' )'; | ||||
I am still unable to reproduce this behavior on my dev box. When I enter '2147483648' (or a higher value) in the search field, I get no error. Spooling the SQL yields the following: 16 0.0055 filter_api.php:998 filter_get_bug_count() Note that the argument to mantis_bugnote_table.id has been set to 2147483647, which is the max value for a 32-bit integer. Looking at the code, this is done in filter_api.php, line 1964:<pre> Re-reading your post, I realize that you're running a 64-bit OS. This probably means that PHP_INT_MAX = 2^63-1, which is of course higher than the max value of mantis_bug_table.id/mantis_bugnote_table.id fields (pgsql integer type = 2^31-1) so the (int) typecast does not sanitize the number value properly. |
|
This could be the reason. Do I have a possibility to force PHP using PHP_INT_MAX=2147483647 ? |
|
You can't change the value of PHP_INT_MAX as it's a PHP core predefined constant. Ideally we should be able to query the DB back-end for the largest acceptable value for a given field and use that to cap the value of $t_search_term, but unfortunately I do not think this can be done with the existing APIs. So, at this time I believe that the only solution is to change filter_api.php to ensure the number is within range for a 32-bit signed integer, but that's an ugly hack. |
|
Yes this is an ugly hack because there could be long numbers as Strings in notes or descriptions and this occurences won't be found. Maybe it will be possible not adding this two lines to the select statement if the number exceeds the range for a 32-bit signed integer? OR (mantis_bugnote_text_table.note ILIKE '%2147483648%') |
|
Why not, after casting to an int, perform a bitwise and against 2^32-1, which will ensure it is never larger than a 32-bit number? |
|
@macarbiter - I was thinking along the same lines, something like
I guess doing a bitwise is probably more efficient (although the performance gain is almost meaningless here)
As I do not have access to a 64-bit system atm, can one of you guys test if the above resolves the problem ? |
|
On second thoughts, the solution schoppi71 mentioned in 0014014:0031417 i.e. not to include the where clauses on the bug and note id fields when the search number is > 2^31-1, probably makes more sense than capping the value as described in 0014014:0031419. This is because when the value is capped, the filter will search the db for bug/note id = 2^31-1, which is not what the user asked for and therefore could cause confusion (in the situation of a user having > 2.1 billion bugs or note id's in their system which I guess is a somewhat unlikely scenario). Please test the attached patch and let me know your feedback. |
|
Do we really need to deal with bits? I am no PHP specialist, but if we have to deal with bits we might also have to deal with things like byte/bit ordering on different processors. |
|
Thanks dregad, the patch works. |
|
Thanks for testing. Having confirmed that on my side as well on a 64-bit VM test box over the week-end, I will make adjustments to the patch to make the hack fixing the error PostgreSQL-specific, in order to avoid regressions since the problem does not exist on MySQL (and I cannot test on other DB platforms). This is not about "dealing with bits", but rather taking into consideration the word size of the underlying operating system [1]. I do not think byte ordering has anything to do with the issue at hand. Normally I agree with you that we should ignore this kind of things in a high-level language. However in that specific case, we do need to do something about it due to the way PostgreSQL handles integers (default 32-bit, error if out of range since 8.0) which impacts normal usage of MantisBT. This may indeed not be the only place where a similar issue can occur (technically speaking, anywhere we deal with integers above the 32-bit limit in relation with DB fields could potentially be affected). However, it's a bit difficult to find out for sure due without many hours of research, to the nature of the problem which is very platform-specific. [1] http://en.wikipedia.org/wiki/Word_%28computer_architecture%29 |
|
I agree that the issue is not caused by byte ordering. I don't like the idea to have such kind of workarounds at this place of code. Hoping that a newer version of adodb might fix the issue for us. |
|
That's just a different (but standard PHP way) of writing constant 2147483647 using hexadecimal notation, which I think makes the code more self-descriptive.
Neither do I, but I really can't think of any other, better way to work around the problem.
Very unlikely. To begin with, PHP drivers for RDBMS do not offer primitive functions to retrieve the maximum possible value for a given DB field. Not to mention that dhx and grangeway are moving away from adodb (see also 0013713:0030836)... I'll upload a revised patch shortly. Let me know if you have an issue with that going into core. |
|
The patch is fine for me. |
|
Good point about putting the additional check within the main if. Thanks for your feedback. Revised patch added (tested on 32-bit mysql + pgsql, will test on 64-bit at when at home later) |
|
Marking as 'acknowledged' not resolved/closed to track that change gets ported to master-2.0.x branch |
|
MantisBT: master 04a5fb5e 2012-03-09 18:21 Details Diff |
Fix 0014014: Search number > 2147483647 fails on 64-bit systems When a numeric search term is entered, the Filter API will only check for matches in the bug and bugnote id fields when the search term is within a valid range. This was never an issue on 32-bit systems, but on 64-bit OS, PostgreSQL throws an "integer out of range" error when executing the query because the search term is cast to (int) and PHP_INT_MAX is greater than the largest value allowed for the numeric DB fields (4-byte int, 2^31-1). This issue does not exist on MySQL as the value is capped to the maximum allowed; behavior was not tested on Oracle, DB2 or MSSQL. The fix for PostgreSQL behavior is a hack, but I can't think of any better solution (ideally, we should be able to query the DB for the maximum allowed value for a field). |
Affected Issues 0014014 |
|
mod - core/filter_api.php | Diff File | ||
MantisBT: master-1.2.x 4618dcd4 2012-03-09 18:21 Details Diff |
Fix 0014014: Search number > 2147483647 fails on 64-bit systems When a numeric search term is entered, the Filter API will only check for matches in the bug and bugnote id fields when the search term is within a valid range. This was never an issue on 32-bit systems, but on 64-bit OS, PostgreSQL throws an "integer out of range" error when executing the query because the search term is cast to (int) and PHP_INT_MAX is greater than the largest value allowed for the numeric DB fields (4-byte int, 2^31-1). This issue does not exist on MySQL as the value is capped to the maximum allowed; behavior was not tested on Oracle, DB2 or MSSQL. The fix for PostgreSQL behavior is a hack, but I can't think of any better solution (ideally, we should be able to query the DB for the maximum allowed value for a field). |
Affected Issues 0014014 |
|
mod - core/filter_api.php | Diff File | ||
MantisBT: master-1.3.x da64caba 2016-11-07 14:41 Committer: dregad Details Diff |
Use DB_MAX_INT constant Replace the fix applied for issue: 0014014 Use a simpler check against DB_MAX_INT constant |
Affected Issues 0014014 |
|
mod - core/filter_api.php | Diff File |