Hi all,
External data can have any form of numbers.
Current PHP can handle them as "string". However PHP7's type hint cannot
handle numeric data well because it only has "int" and "float" hints.
There are cases that programmer want/need to handle any numeric values.
e.g. JSON numeric, Database numeric, PHP's array key beyonds INT min/max,
Values for BCMath/GMP, etc. It's common for 32 bit platforms. For example,
we cannot do query database safely with "int" type hint.
e.g.
function get_some_db_record(int $id) {}
Most databases uses 64 bit signed int for database IDs, but this code limits
$id to 32 bit signed int for 32 bit platforms. There are databases that
allow
unsigned 64 bit int ID.
To avoid this problem, users must use "string" type hint and have to
validate
parameter by themselves. This ruins benefits of type hint. Most PHP will not
use "string" type hint even if apps need large numbers.
How about have "numeric" type hint that accepts any format/class(GMP)
of numeric values?
function foo(numeric $var) { // do something useful with numeric value }
To be honest, I would like to have StrictSTH RFC behavior for weak mode
int/float type hints to make sure "int"/"float" has integer/float
form/value always,
but "numeric" type hint may do the job. One function with "int"/"float"
type hint
could break app with current type hint implementation, though. i.e. Working
app suddenly emits fatal error and exits when database/json returns value
beyond int/float.
http://3v4l.org/6J0bZ (See how it works with large string integer value)
Any comments?
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi!
External data can have any form of numbers.
Current PHP can handle them as "string". However PHP7's type hint cannot
handle numeric data well because it only has "int" and "float" hints.
This is exactly what's wrong with strict typing in PHP. However, if you
use real numeric string and do not enable strict typing - it works just
fine. We don't need more types for this.
There are cases that programmer want/need to handle any numeric values.
There also cases when programmer needs to handle Roman numbers, phone
numbers, valid XML strings and TCP/IP headers. But we should not add
types into the language for those.
To avoid this problem, users must use "string" type hint and have to
validate
parameter by themselves. This ruins benefits of type hint. Most PHP will not
Typing is not solution for every data restriction, especially not in
PHP. If you app needs strings that can not be represented by PHP basic
types, you need custom validation code.
but "numeric" type hint may do the job. One function with "int"/"float"
type hint
could break app with current type hint implementation, though. i.e. Working
If you type your parameter, then you declare "I want this to fail if the
parameter is not of this type". Then you can't complain when it fails -
that's exactly what you asked for.
--
Stas Malyshev
smalyshev@gmail.com
On Tue, Apr 28, 2015 at 6:00 PM, Stanislav Malyshev smalyshev@gmail.com
wrote:
Hi!
External data can have any form of numbers.
Current PHP can handle them as "string". However PHP7's type hint cannot
handle numeric data well because it only has "int" and "float" hints.This is exactly what's wrong with strict typing in PHP. However, if you
use real numeric string and do not enable strict typing - it works just
fine. We don't need more types for this.There are cases that programmer want/need to handle any numeric values.
There also cases when programmer needs to handle Roman numbers, phone
numbers, valid XML strings and TCP/IP headers. But we should not add
types into the language for those.To avoid this problem, users must use "string" type hint and have to
validate
parameter by themselves. This ruins benefits of type hint. Most PHP will
notTyping is not solution for every data restriction, especially not in
PHP. If you app needs strings that can not be represented by PHP basic
types, you need custom validation code.but "numeric" type hint may do the job. One function with "int"/"float"
type hint
could break app with current type hint implementation, though. i.e.
WorkingIf you type your parameter, then you declare "I want this to fail if the
parameter is not of this type". Then you can't complain when it fails -
that's exactly what you asked for.
I agree with Stanislav here, if you want to accept any type of number, its
easy enough to add your own checking to do that with the wonderful
is_numeric. And for simplicity, make an invalidArgument method that you can
call after manually checking if arguments are wrong: http://3v4l.org/r0qO0
http://3v4l.org/r0qO0 Works for all versions this tool runs as well.
-Ryan
--
Stas Malyshev
smalyshev@gmail.com
Hi Stas and Ryan,
External data can have any form of numbers.
Current PHP can handle them as "string". However PHP7's type hint cannot
handle numeric data well because it only has "int" and "float" hints.This is exactly what's wrong with strict typing in PHP. However, if you
use real numeric string and do not enable strict typing - it works just
fine. We don't need more types for this.There are cases that programmer want/need to handle any numeric values.
There also cases when programmer needs to handle Roman numbers, phone
numbers, valid XML strings and TCP/IP headers. But we should not add
types into the language for those.To avoid this problem, users must use "string" type hint and have to
validate
parameter by themselves. This ruins benefits of type hint. Most PHP
will notTyping is not solution for every data restriction, especially not in
PHP. If you app needs strings that can not be represented by PHP basic
types, you need custom validation code.but "numeric" type hint may do the job. One function with "int"/"float"
type hint
could break app with current type hint implementation, though. i.e.
WorkingIf you type your parameter, then you declare "I want this to fail if the
parameter is not of this type". Then you can't complain when it fails -
that's exactly what you asked for.I agree with Stanislav here, if you want to accept any type of number, its
easy enough to add your own checking to do that with the wonderful
is_numeric. And for simplicity, make an invalidArgument method that you can
call after manually checking if arguments are wrong: http://3v4l.org/r0qO0
http://3v4l.org/r0qO0 Works for all versions this tool runs as well.
The objective to have type "hint" is to remove such checks by users, isn't
it?
Do you really think all users will write such code for database/json/etc
values?
The issue is that weak mode type hint is not weak at all. It forces to
have
machine native type rather than it's data form.
PHP apps are easily broken by too large value because PHP stops execution
by fatal error. i.e. DoS became easy. I will never write such code, but I
don't
want to check and fix library that I would like to use. I don't think I can
manage
programmers to do that even if they are under my control.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Yasuo Ohgaki wrote:
I agree with Stanislav here, if you want to accept any type of number, its
easy enough to add your own checking to do that with the wonderful
is_numeric. And for simplicity, make an invalidArgument method that you can
call after manually checking if arguments are wrong: http://3v4l.org/r0qO0
http://3v4l.org/r0qO0 Works for all versions this tool runs as well.The issue is that weak mode type hint is not weak at all. It forces to
have
machine native type rather than it's data form.
A solution for this issue has been proposed by the "Big Integer Support"
RFC which has been withdrawn. It's too late for PHP 7.0 to re-open it,
but it might be reasonable to to so for PHP 7.1.
--
Christoph M. Becker
Hi Christoph,
On Wed, Apr 29, 2015 at 9:33 AM, Ryan Pallas derokorian@gmail.com
wrote:I agree with Stanislav here, if you want to accept any type of number,
its
easy enough to add your own checking to do that with the wonderful
is_numeric. And for simplicity, make an invalidArgument method that you
can
call after manually checking if arguments are wrong: *
http://3v4l.org/r0qO0
http://3v4l.org/r0qO0* Works for all versions this tool runs as well.The issue is that weak mode type hint is not weak at all. It forces to
have
machine native type rather than it's data form.A solution for this issue has been proposed by the "Big Integer Support"
RFC which has been withdrawn. It's too late for PHP 7.0 to re-open it,
but it might be reasonable to to so for PHP 7.1.
I don't think breaking a lot of code under 32 bit machines with PHP 7.0
is not good thing to do.
In addition, current code does not even allow GMP object as "int".
http://3v4l.org/GiklL
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
This has been a big issue that I have ran into many times in the past for
large framework projects, instead of building it out with "strict" types
like: int, float, string, exc... It makes more sense to allow a user to
define a psudo-type themselves which PHP will pass the arguments into to be
"cleaned" by the user then let the function deal with the arguments.
For example:
function force_int($value){
return (int) $value;
}
function must_be_string($v){
if(!is_string($v)){
throw new Exception("Not String");
}
return (string) $v;
}
function foo(*force_int $val, *must_be_string $str){
// $val will always be an int if it ever gets here
// $str will always be a string if it gets here
echo $val, " ", $str;
}
foo("foo", "bar"); // returns '0 bar'
foo("1", "2"); // returns '1 2'
foo(1, 2); // fatal error because second argument threw exception
foo(1, "2") // returns '1 2'
foo("hi", 2) // fatal error because second argument threw exception
foo("hi", "2") // returns '0 2';
Hi Christoph,
On Thu, Apr 30, 2015 at 6:27 AM, Christoph Becker cmbecker69@gmx.de
wrote:On Wed, Apr 29, 2015 at 9:33 AM, Ryan Pallas derokorian@gmail.com
wrote:I agree with Stanislav here, if you want to accept any type of number,
its
easy enough to add your own checking to do that with the wonderful
is_numeric. And for simplicity, make an invalidArgument method that
you
can
call after manually checking if arguments are wrong: *
http://3v4l.org/r0qO0
http://3v4l.org/r0qO0* Works for all versions this tool runs as
well.The issue is that weak mode type hint is not weak at all. It forces
to
have
machine native type rather than it's data form.A solution for this issue has been proposed by the "Big Integer Support"
RFC which has been withdrawn. It's too late for PHP 7.0 to re-open it,
but it might be reasonable to to so for PHP 7.1.I don't think breaking a lot of code under 32 bit machines with PHP 7.0
is not good thing to do.In addition, current code does not even allow GMP object as "int".
http://3v4l.org/GiklLRegards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Nathan,
This has been a big issue that I have ran into many times in the past for
large framework projects, instead of building it out with "strict" types
like: int, float, string, exc... It makes more sense to allow a user to
define a psudo-type themselves which PHP will pass the arguments into to be
"cleaned" by the user then let the function deal with the arguments.For example:
function force_int($value){
return (int) $value;
}
function must_be_string($v){
if(!is_string($v)){
throw new Exception("Not String");
}
return (string) $v;
}function foo(*force_int $val, *must_be_string $str){
// $val will always be an int if it ever gets here
// $str will always be a string if it gets here
echo $val, " ", $str;
}
foo("foo", "bar"); // returns '0 bar'
foo("1", "2"); // returns '1 2'
foo(1, 2); // fatal error because second argument threw exception
foo(1, "2") // returns '1 2'
foo("hi", 2) // fatal error because second argument threw exception
foo("hi", "2") // returns '0 2';
I agree. Forcing type is headache and such check is useful.
The problem with this approach is overhead. I would like to resolve this in
2 ways.
- DbC - Check parameter types during development by DbC and make
sure all callee satisfies contract. - True weak type hint - Make weak mode type hint truly weak. Accept
any form of the specified types.
Since we won't have DbC for PHP 7.0, I'll discuss only option 2.
function foo(int $i) {
switch(gettype($i)) {
case 'integer':
case 'float":
foo_numeric($i);
break;
default:
// We don't want to accept gmp/string
throw new Exception('Type error');
}
}
Ideal solution would be DbC. Anyway, above example is a little more
efficient
than calling pseudo type checker functions (for now). Pseudo type checker
is useful and requires less code. I'm neutral to have it or not.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Yasuo,
Yasuo Ohgaki wrote:
A solution for this issue has been proposed by the "Big Integer Support"
RFC which has been withdrawn. It's too late for PHP 7.0 to re-open it,
but it might be reasonable to to so for PHP 7.1.I don't think breaking a lot of code under 32 bit machines with PHP 7.0
is not good thing to do.
I don't disagree, but for better or worse this ship has sailed: the
scheduled feature freeze for PHP 7.0 has been weeks ago. See also the
respective discussion in
http://marc.info/?l=php-internals&m=143022755119608.
--
Christoph M. Becker
Hi Christoph,
Yasuo Ohgaki wrote:
On Thu, Apr 30, 2015 at 6:27 AM, Christoph Becker cmbecker69@gmx.de
wrote:A solution for this issue has been proposed by the "Big Integer Support"
RFC which has been withdrawn. It's too late for PHP 7.0 to re-open it,
but it might be reasonable to to so for PHP 7.1.I don't think breaking a lot of code under 32 bit machines with PHP 7.0
is not good thing to do.I don't disagree, but for better or worse this ship has sailed: the
scheduled feature freeze for PHP 7.0 has been weeks ago. See also the
respective discussion in
http://marc.info/?l=php-internals&m=143022755119608.
The ship is still in dock and under construction. If there is problem/issue,
it should be resolved.
Working apps suddenly end with fatal error without reasonable reason
should be fixed before sailing. IMHO.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi!
The objective to have type "hint" is to remove such checks by users,
isn't it?
No, not really. The objective is to ensure type of the parameter. If you
checks are not limited to types, then typing is not going to help, and I
don't think inventing special built-in type for each narrow use case is
a good way to go.
Do you really think all users will write such code for database/json/etc
values?
No, I don't think all users need such checks. But those that do will
have to write the code for it.
The issue is that weak mode type hint is not weak at all. It forces to
have
machine native type rather than it's data form.
PHP types are not machine native types. But yes, it forces PHP type -
that's why it is type check.
PHP apps are easily broken by too large value because PHP stops execution
by fatal error. i.e. DoS became easy. I will never write such code, but
That is a different issue. If you don't want fatal error, a) we have
proposal to make those exceptions, b) it is not fixed by introducing
pseudo-types for narrow use cases, since it is a completely different
issue.
I don't
want to check and fix library that I would like to use. I don't think I
can manage
programmers to do that even if they are under my control.
You are saying type checking which produces fatal errors does not match
your use case. OK, I can sympathize, but how introducing more
pseudo-types helps? You just fix one narrow use case that you have right
now while leaving the problem still in the same place. That's not a good
way to address it.
Stas Malyshev
smalyshev@gmail.com
Hi Stas,
On Thu, Apr 30, 2015 at 8:24 AM, Stanislav Malyshev smalyshev@gmail.com
wrote:
The objective to have type "hint" is to remove such checks by users,
isn't it?No, not really. The objective is to ensure type of the parameter. If you
checks are not limited to types, then typing is not going to help, and I
don't think inventing special built-in type for each narrow use case is
a good way to go.
If you need to force to map value to PHP type, you have "strict" mode.
"Weak"
mode is just too strict currently even if PHP handled int/float/string as
"integer"/"float" including invalid values traditionally.
New PHP7 type hint doesn't allow "valid" int/float/string as
"integer"/"float".
This is unintuitive change for most PHP users because of weakly typed
tradition.
I'm sure there will be so many codes that misuses type hint if there is no
"numeric" type hint.
Do you really think all users will write such code for database/json/etc
values?No, I don't think all users need such checks. But those that do will
have to write the code for it.
Users must validate all inputs that cannot be trusted. e.g. Users must
validate is JSON numeric value has numeric form expected.
I think most users will just use type "hint" because users assumes it's a
"hint", not type enforcement, and it works well for small values.
The issue is that weak mode type hint is not weak at all. It forces to
have
machine native type rather than it's data form.PHP types are not machine native types. But yes, it forces PHP type -
that's why it is type check.
Type hint is better to stay as "hint" under weak mode. IMO.
PHP apps are easily broken by too large value because PHP stops execution
by fatal error. i.e. DoS became easy. I will never write such code, butThat is a different issue. If you don't want fatal error, a) we have
proposal to make those exceptions, b) it is not fixed by introducing
pseudo-types for narrow use cases, since it is a completely different
issue.
It's alternatives. Resuming execution with exception is harder.
Customizable pseudo-type is too late for PHP 7.0. We do decided
to introduce basic type hint and it has issue to be resolved. Let's
concentrate on resolution.
I don't
want to check and fix library that I would like to use. I don't think I
can manage
programmers to do that even if they are under my control.You are saying type checking which produces fatal errors does not match
your use case. OK, I can sympathize, but how introducing more
pseudo-types helps? You just fix one narrow use case that you have right
now while leaving the problem still in the same place. That's not a good
way to address it.
I'm not concerning myself, but I'm worrying about users to write
apps/libraries
that can cause DoS easily. I don't want to see my my apps emit fatal error
by upgrading library just because library author decided to use type hint
wrongly.
Current type hint implementation/spec does not have protection/prevention
at all.
Having "numeric" type hint or StrictSTH RFC concept adoption are
possible resolutions. If there is better resolution, I appreciate it.
BTW, GMP integer is already integrated into PHP why not treat GMP as int?
It's type "hint", isn't it?
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi!
If you need to force to map value to PHP type, you have "strict" mode.
"Weak"
mode is just too strict currently even if PHP handled int/float/string as
"integer"/"float" including invalid values traditionally.
That is what was decided by votes - to make type conversions fail on
values that can not be represented by these types.
New PHP7 type hint doesn't allow "valid" int/float/string as
"integer"/"float".
Because "string having lots of digits" and "integer" is not the same
thing - the latter has limits, the former does not. You can not really
use them interchangeably.
This is unintuitive change for most PHP users because of weakly typed
tradition.
I don't think it's correct - there was never tradition that any string
can be successfully represented in integer type. It's just not possible
- integer type is a limited type and string is not. The only change was
made that if it can not be represented, the parameter typing produces
failure. I'm not a big fan of it, but that's what the vote decided, so
that's what we have.
I'm sure there will be so many codes that misuses type hint if there is no
"numeric" type hint.
I'm also sure their problem is not in absence of type that says "string
matching regexp [0-9]+" since I do not see a use case which such type
would improve. You can not do anything you do with int with such type,
and if you need to so string pattern validation, that's not function of
the type system, at least not in PHP.
Users must validate all inputs that cannot be trusted. e.g. Users must
validate is JSON numeric value has numeric form expected.
Surely, but we won't have scalar types of "url", "email address", "host
name", "IPv6 IP address", "phone number in Brazil" or "russian car
license plate" - even though I'm sure validating such strings has a lot
of applications. It's just not what types in PHP do. Of course, you can
have user types implementing all that - nothing prevents you from
doing it.
PHP types are not machine native types. But yes, it forces PHP type - that's why it is *type* check.
Type hint is better to stay as "hint" under weak mode. IMO.
I'm not sure I understand what you mean here.
It's alternatives. Resuming execution with exception is harder.
Customizable pseudo-type is too late for PHP 7.0. We do decided
to introduce basic type hint and it has issue to be resolved. Let's
concentrate on resolution.
That's what we're doing, and the resolution should not be introducing
ad-hoc pseudo-types for specific use cases. For 7.0, the resolution can
not be introducing anything at all, as April 29 > March 15, but more
long-term it is also not the right approach.
Having "numeric" type hint or StrictSTH RFC concept adoption are
possible resolutions. If there is better resolution, I appreciate it.
I don't see what specifically you're trying to resolve. If the case is
to validate numeric strings, there are functions for it. If the case is
to avoid failures on dirty data, your only option is pre-validation,
since strict validation is what was decided for parameter types. If
you'd like to change that, you can submit an RFC for 7.1, but as it was
just recently decided by vote otherwise, I don't see how such RFC can
succeed.
BTW, GMP integer is already integrated into PHP why not treat GMP as int?
Because GMP object is not int. It can be convertable to int, but the
question of conversion failure still remains.
It's type "hint", isn't it?
I'm not sure I understand what you mean here.
--
Stas Malyshev
smalyshev@gmail.com
Hi Stas,
On Thu, Apr 30, 2015 at 9:20 AM, Stanislav Malyshev smalyshev@gmail.com
wrote:
If you need to force to map value to PHP type, you have "strict" mode.
"Weak"
mode is just too strict currently even if PHP handled int/float/string as
"integer"/"float" including invalid values traditionally.That is what was decided by votes - to make type conversions fail on
values that can not be represented by these types.
How many of us are expected that
mydb_find_by_id(INT_MAX+1);
Note: INT_MAX+1 is pseudo integer string value.
fails with fatal error? I guess it's not many.
(This is one of the main reason why I strongly supported CoerciveSTH RFC.
Sorry, I wrote "Strict" where I should write "Coercive". It was confusing.)
The max is only about 2 billions under 32 bit platforms.
Please don't think only for servers, there will be number of IoT devices
that
can use PHP to control it.
New PHP7 type hint doesn't allow "valid" int/float/string as
"integer"/"float".
Because "string having lots of digits" and "integer" is not the same
thing - the latter has limits, the former does not. You can not really
use them interchangeably.
It's fine to enforce specific type under strict mode.
I guess basic design of current scalar type hint is to switch weak and
strict mode interchangeably. That's the reason why I proposed "numeric"
type hint here rather than CoerciveSTH RFC like behavior even if I prefer
it.
This is unintuitive change for most PHP users because of weakly typed
tradition.
I don't think it's correct - there was never tradition that any string
can be successfully represented in integer type. It's just not possible
- integer type is a limited type and string is not. The only change was
made that if it can not be represented, the parameter typing produces
failure. I'm not a big fan of it, but that's what the vote decided, so
that's what we have.
Users are recognized record ID as integer even if it's a string integer
indeed.
I think many, if not most, users are not aware that db record ID field is
"string integer" . As long as users do not apply arithmetic, string integer
worked perfectly with PHP. I'm saying this is a tradition.
I'm sure there will be so many codes that misuses type hint if there is no
"numeric" type hint.
I'm also sure their problem is not in absence of type that says "string
matching regexp [0-9]+" since I do not see a use case which such type
would improve. You can not do anything you do with int with such type,
and if you need to so string pattern validation, that's not function of
the type system, at least not in PHP.
Most obvious use case is record ID that I mentioned above, but it's not
limited to record ID. e.g. all database numeric values/JSON numeric/
PHP array integer type key beyond INT_MAX/MIN.
Users must validate all inputs that cannot be trusted. e.g. Users must
validate is JSON numeric value has numeric form expected.Surely, but we won't have scalar types of "url", "email address", "host
name", "IPv6 IP address", "phone number in Brazil" or "russian car
license plate" - even though I'm sure validating such strings has a lot
of applications. It's just not what types in PHP do. Of course, you can
have user types implementing all that - nothing prevents you from
doing it.
String can represent any values so users must be careful, but not int
and float.
The reason why strictly typed languages are safer, is "int" is int
always. I don't think strict typed language automatically safer than PHP as
many strictly typed language's web frameworks work seamlessly for types,
but it's safer actually because "integer like value" is int almost always.
PHP types are not machine native types. But yes, it forces PHP type -
that's why it is *type* check.
Type hint is better to stay as "hint" under weak mode. IMO.
I'm not sure I understand what you mean here.
Great. I think "int"/"float" type hint is too strict even under weak mode.
Therefore, I want to have "numeric" type hint at least.
It's alternatives. Resuming execution with exception is harder.
Customizable pseudo-type is too late for PHP 7.0. We do decided
to introduce basic type hint and it has issue to be resolved. Let's
concentrate on resolution.That's what we're doing, and the resolution should not be introducing
ad-hoc pseudo-types for specific use cases. For 7.0, the resolution can
not be introducing anything at all, as April 29 > March 15, but more
long-term it is also not the right approach.
Having "numeric" type hint or CoerciveSTH RFC concept adoption are
possible resolutions. If there is better resolution, I appreciate it.I don't see what specifically you're trying to resolve. If the case is
to validate numeric strings, there are functions for it. If the case is
to avoid failures on dirty data, your only option is pre-validation,
since strict validation is what was decided for parameter types. If
you'd like to change that, you can submit an RFC for 7.1, but as it was
just recently decided by vote otherwise, I don't see how such RFC can
succeed.
Having "numeric" or accepting huge value(including GMP) for "int"/"float"
should be acceptable. IMHO.
As I wrote, huge numbers are valid data for databases. I don't want to have
DoS incident just because PHP limits numbers to native type range
while databases accept these larger values as valid values.
BTW, GMP integer is already integrated into PHP why not treat GMP as int?
Because GMP object is not int. It can be convertable to int, but the
question of conversion failure still remains.
I think it's OK to fail when "strict" mode is enabled.
It's type "hint", isn't it?
I'm not sure I understand what you mean here.
We may have integrated GMP float in near future also. Accepting compatible
value/type is mandatory if it's a type "hint" for weak mode. I don't think
we
decided to have type declaration(type enforcement), do we?
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi!
How many of us are expected that
mydb_find_by_id(INT_MAX+1);
Note: INT_MAX+1 is pseudo integer string value.fails with fatal error? I guess it's not many.
I'm not sure what is the meaning of "INT_MAX+1 is pseudo integer string
value" - if it fits the integer, it's the integer, if it's a string that
looks like decimal rendering of a natural number that is equal to
INT_MAX+1, then it's not an integer, it's just a string. It can not be
used as integer.
If somebody voted on this RFC without expecting it, that means they did
not understand the RFC. I don't know what can be done about people
voting for RFCs they don't understand - we can't take an exam before
voting. We expect people first understand it then vote, and assume
everybody who votes understands what it means and accepts the
consequences.
Users are recognized record ID as integer even if it's a string integer
indeed.
There's no such thing as "string integer". It's either string - which
can be convertible or not convertible to integer - and there's actual
integer value.
I think many, if not most, users are not aware that db record ID field is
"string integer" . As long as users do not apply arithmetic, string integer
worked perfectly with PHP. I'm saying this is a tradition.
I don't see where you derive such "tradition" from. PHP never worked
this way. The only difference is that before you'd get something like
INT_MAX or -INT_MAX or 0 or whatever random value after conversion. I
don't see how that would be better than fatal error, really.
Most obvious use case is record ID that I mentioned above, but it's not
limited to record ID. e.g. all database numeric values/JSON numeric/
PHP array integer type key beyond INT_MAX/MIN.
You can't have integer array key beyond integer, that is a logical
impossibility. As for external values, external value can be anything -
row of ones, random binary noise, string "porcupine", anything. You
can't expect it to be convertible to integer. You'll have to check
anyway. "numeric" type is not going to help you.
Great. I think "int"/"float" type hint is too strict even under weak mode.
Therefore, I want to have "numeric" type hint at least.
I don't see how this helps anything. "numeric" is not a type, it is a
validation of a string form. As such, it has very little to do with PHP
types.
Having "numeric" or accepting huge value(including GMP) for "int"/"float"
should be acceptable. IMHO.
That negates the whole purpose of having "int" type, since what comes
out of it is not int anymore.
As I wrote, huge numbers are valid data for databases. I don't want to have
String "porcupine" is a valid data for database too. Should we have a
type that says "number or string 'porcupine'"? Both are valid data for
DB. But they do not form a type.
DoS incident just because PHP limits numbers to native type range
while databases accept these larger values as valid values.
Databases accept anything as valid values. If you expect this to fit
PHP's scalar types, you need to check. Otherwise, you need to use PHP
type that can accommodate anything, namely - string.
We may have integrated GMP float in near future also. Accepting compatible
value/type is mandatory if it's a type "hint" for weak mode. I don't
think we
decided to have type declaration(type enforcement), do we?
We can accept compatible values. The question is what to do with
incompatible values. Accepting those is not really possible within
typed parameters semantics.
--
Stas Malyshev
smalyshev@gmail.com
Hi Stas,
On Thu, Apr 30, 2015 at 12:05 PM, Stanislav Malyshev smalyshev@gmail.com
wrote:
How many of us are expected that
mydb_find_by_id(INT_MAX+1);
Note: INT_MAX+1 is pseudo integer string value.fails with fatal error? I guess it's not many.
I'm not sure what is the meaning of "INT_MAX+1 is pseudo integer string
value" - if it fits the integer, it's the integer, if it's a string that
looks like decimal rendering of a natural number that is equal to
INT_MAX+1, then it's not an integer, it's just a string. It can not be
used as integer.If somebody voted on this RFC without expecting it, that means they did
not understand the RFC. I don't know what can be done about people
voting for RFCs they don't understand - we can't take an exam before
voting. We expect people first understand it then vote, and assume
everybody who votes understands what it means and accepts the
consequences.
I hope everyone voted "yes" and users realize the consequence.
I don't have problem with this if I could write ALL of PHP code that I
use.
Obviously, I cannot have that much amount of time.
Users are recognized record ID as integer even if it's a string integer
indeed.
There's no such thing as "string integer". It's either string - which
can be convertible or not convertible to integer - and there's actual
integer value.
No there is not.
I have read so many buggy casts for record IDs in past.
i.e. "SELECT * FROM table WHERE id = ". (int)$id
"Integer like string" must stay as "string" to avoid bugs.
I wonder about how many of users write function with correct type hint.
Wrong: mydb_find_by_id(int $id) { // find it }
Correct : mydb_find_by_id(string $id) { // find it }
"int" Cast is bad. Incorrect "int" type hint worse as it could trigger DoS.
I think many, if not most, users are not aware that db record ID field is
"string integer" . As long as users do not apply arithmetic, string
integer
worked perfectly with PHP. I'm saying this is a tradition.I don't see where you derive such "tradition" from. PHP never worked
this way. The only difference is that before you'd get something like
INT_MAX or -INT_MAX or 0 or whatever random value after conversion. I
don't see how that would be better than fatal error, really.
Most obvious use case is record ID that I mentioned above, but it's not
limited to record ID. e.g. all database numeric values/JSON numeric/
PHP array integer type key beyond INT_MAX/MIN.You can't have integer array key beyond integer, that is a logical
impossibility. As for external values, external value can be anything -
row of ones, random binary noise, string "porcupine", anything. You
can't expect it to be convertible to integer. You'll have to check
anyway. "numeric" type is not going to help you.
Whether like it or not, database values are treated as string. Some of
values are treated as int, but integer columns like record IDs are treated
as "integer like string". PHP Users didn't care much about types used,
and they used "integer like string" as it is.
As a result, database record ID/etc are treated correctly.
I saw many buggy int casts for record IDs. Therefore, I'm expecting buggy
type hints as well.
There should be relaxed type hint for numeric types.
- Have numeric
or - Relax weak mode int/float type hint like CoerciveSTH
Great. I think "int"/"float" type hint is too strict even under weak mode.
Therefore, I want to have "numeric" type hint at least.
I don't see how this helps anything. "numeric" is not a type, it is a
validation of a string form. As such, it has very little to do with PHP
types.
numeric type is useful for numbers that could be out of PHP int/float range.
Having "numeric" or accepting huge value(including GMP) for "int"/"float"
should be acceptable. IMHO.
That negates the whole purpose of having "int" type, since what comes
out of it is not int anymore.
If anyone really need some parameter to be int/float, they can use "strict"
mode.
Isn't it enough?
As I wrote, huge numbers are valid data for databases. I don't want to
haveString "porcupine" is a valid data for database too. Should we have a
type that says "number or string 'porcupine'"? Both are valid data for
DB. But they do not form a type.DoS incident just because PHP limits numbers to native type range
while databases accept these larger values as valid values.Databases accept anything as valid values. If you expect this to fit
PHP's scalar types, you need to check. Otherwise, you need to use PHP
type that can accommodate anything, namely - string.
It's not all, but the main issue here is 32 bit CPU & PHP int is too small
for
database record IDs.
We may have integrated GMP float in near future also. Accepting compatible
value/type is mandatory if it's a type "hint" for weak mode. I don't
think we
decided to have type declaration(type enforcement), do we?We can accept compatible values. The question is what to do with
incompatible values. Accepting those is not really possible within
typed parameters semantics.
To maximize compatibility, arbitrarily size of int/float like string/value
should be
accepted as numeric(or int/float).
We have issues for type handling. One is type hint spec/behavior, another
is
cast without any errors. We need "cast with errors" feature so that users
can
handle range error easily.
I'm grateful if int/float restriction is relaxed. Otherwise, having
"numeric" type hint
is mandatory to avoid type massive hint misuse. Writing big warning "Do not
use
'int' type hint for database record IDs/etc, but use 'string' type hint and
validate by
yourself" wouldn't help much.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi!
"int" Cast is bad. Incorrect "int" type hint worse as it could trigger DoS.
I do not see any potential for DoS here. Trying to assign security
implications so it looks like disagreeing with you jeopardizes security
is not a good idea. If your code accepts non-numeric data and puts it to
functions that except integers without validation, it is bad code and
"numeric" hint would not help here, as unvalidated data can contain
anything. If unexpected input causes denial of service in your code, it
is a code architecture problem, which should not be solved by adding
stuff to PHP.
It's not all, but the main issue here is 32 bit CPU & PHP int is too
small for
database record IDs.
Correct way to go there is treating these IDs as strings or objects and
having code that handles them properly. If they do not fit PHP int, they
should not be used with functions that expect int.
To maximize compatibility, arbitrarily size of int/float like
string/value should be
accepted as numeric(or int/float).
No, it should not be, since they are neither int nor float.
--
Stas Malyshev
smalyshev@gmail.com
On Wed, Apr 29, 2015 at 10:42 PM, Stanislav Malyshev smalyshev@gmail.com
wrote:
Hi!
"int" Cast is bad. Incorrect "int" type hint worse as it could trigger
DoS.I do not see any potential for DoS here. Trying to assign security
implications so it looks like disagreeing with you jeopardizes security
is not a good idea. If your code accepts non-numeric data and puts it to
functions that except integers without validation, it is bad code and
"numeric" hint would not help here, as unvalidated data can contain
anything. If unexpected input causes denial of service in your code, it
is a code architecture problem, which should not be solved by adding
stuff to PHP.It's not all, but the main issue here is 32 bit CPU & PHP int is too
small for
database record IDs.Correct way to go there is treating these IDs as strings or objects and
having code that handles them properly. If they do not fit PHP int, they
should not be used with functions that expect int.To maximize compatibility, arbitrarily size of int/float like
string/value should be
accepted as numeric(or int/float).No, it should not be, since they are neither int nor float.
I have to strongly agree with Stanislaw here. If you are getting strings
from the DB because they don't fit in int, leave them as strings. If
someone breaks the code by adding the wrong type hints, then they have
broken the code.
Stop trying to fix clever idiots from shooting themselves in the foot. The
standard result from these actions is to make life a pain for regular or
better programmers while only adding mild speed bumps to those clever
idiots.
Things like a numeric type will only encourage the clever idiots to write
half broken code.
We just had to fix ZIP codes because the look like integers, so they get
processed and stored as integers. But this can break things when dealing
with New Jersey, which has ZIP codes like 07101. If you drop the lead zero,
then you have a different string/number and it can (and does) cause issues.
Walter
--
Stas Malyshev
smalyshev@gmail.com--
--
The greatest dangers to liberty lurk in insidious encroachment by men of
zeal, well-meaning but without understanding. -- Justice Louis D. Brandeis
Stop trying to fix clever idiots from shooting themselves in the foot. The
standard result from these actions is to make life a pain for regular or
better programmers while only adding mild speed bumps to those clever
idiots.Things like a numeric type will only encourage the clever idiots to write
half broken code.
Hello, just want to chip in.
I use "INT UNSIGNED" for the MySQL primary keys since ages, because
negative primary keys make no sense. Well, mostly ID's for the records
actually can stay strings, but I will have to remember to use a string type
hint every time I pass a record ID. I expect a lot of times to forget that
and write int...
I was bitten a few times by the limits of 32 bit integer sizes too (moved
to a 64 bit server that time), but there are also unsigned 64 bit integers
that can and will be used in math operations and passed around. And we
don't have the "unsigned int".
Okay, we have GMP. I will have to use it. But let me just ask - if I work
with a DB handling 64 bit integers (all I know handle them) or use a
DECIMAL field - automaticly use GMP then? Oh gosh....
Arvids.
On Wed, Apr 29, 2015 at 11:40 PM, Arvids Godjuks arvids.godjuks@gmail.com
wrote:
Stop trying to fix clever idiots from shooting themselves in the foot. The
standard result from these actions is to make life a pain for regular or
better programmers while only adding mild speed bumps to those clever
idiots.Things like a numeric type will only encourage the clever idiots to write
half broken code.Hello, just want to chip in.
I use "INT UNSIGNED" for the MySQL primary keys since ages, because
negative primary keys make no sense. Well, mostly ID's for the records
actually can stay strings, but I will have to remember to use a string type
hint every time I pass a record ID. I expect a lot of times to forget that
and write int...
I was bitten a few times by the limits of 32 bit integer sizes too (moved
to a 64 bit server that time), but there are also unsigned 64 bit integers
that can and will be used in math operations and passed around. And we
don't have the "unsigned int".Okay, we have GMP. I will have to use it. But let me just ask - if I work
with a DB handling 64 bit integers (all I know handle them) or use a
DECIMAL field - automaticly use GMP then? Oh gosh....Arvids.
I think you point out an interesting problem. It sounds like you designed
the DB in isolation from the languages that would use it and then
discovered after the fact that using the entire space (because it sounds
like a good idea in isolation) can make life tough. Using a signed int
would have only reduced your space by half. In many cases, it you need that
extra space, you need more than twice and the difference between signed and
unsigned is not relevant. If the code and DB are matched, then you don't
have these problem. I'd suggest we make sure that we fix it in the right
location (I don't think a numeric type is the right location).
Walter
--
The greatest dangers to liberty lurk in insidious encroachment by men of
zeal, well-meaning but without understanding. -- Justice Louis D. Brandeis
Hi Arvids,
On Thu, Apr 30, 2015 at 3:40 PM, Arvids Godjuks arvids.godjuks@gmail.com
wrote:
Stop trying to fix clever idiots from shooting themselves in the foot. The
standard result from these actions is to make life a pain for regular or
better programmers while only adding mild speed bumps to those clever
idiots.Things like a numeric type will only encourage the clever idiots to write
half broken code.Hello, just want to chip in.
I use "INT UNSIGNED" for the MySQL primary keys since ages, because
negative primary keys make no sense. Well, mostly ID's for the records
actually can stay strings, but I will have to remember to use a string type
hint every time I pass a record ID. I expect a lot of times to forget that
and write int...
I was bitten a few times by the limits of 32 bit integer sizes too (moved
to a 64 bit server that time), but there are also unsigned 64 bit integers
that can and will be used in math operations and passed around. And we
don't have the "unsigned int".
Use of unsigned int8 for ID makes sense almost always if database supports
it.
I may do such mistake even if I know I should use "string" (or "numeric")
for record IDs once I
start using type hints.
Okay, we have GMP. I will have to use it. But let me just ask - if I work
with a DB handling 64 bit integers (all I know handle them) or use a
DECIMAL field - automaticly use GMP then? Oh gosh....
I'm planning to introduce type affinity like SQLite. Then appropriate types
for the value may
be used automatically/semi-automatically. It's good for both security and
performance.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Arvids,
On Thu, Apr 30, 2015 at 3:40 PM, Arvids Godjuks arvids.godjuks@gmail.com
wrote:Stop trying to fix clever idiots from shooting themselves in the foot. The
standard result from these actions is to make life a pain for regular or
better programmers while only adding mild speed bumps to those clever
idiots.Things like a numeric type will only encourage the clever idiots to write
half broken code.Hello, just want to chip in.
I use "INT UNSIGNED" for the MySQL primary keys since ages, because
negative primary keys make no sense. Well, mostly ID's for the records
actually can stay strings, but I will have to remember to use a string type
hint every time I pass a record ID. I expect a lot of times to forget that
and write int...
I was bitten a few times by the limits of 32 bit integer sizes too (moved
to a 64 bit server that time), but there are also unsigned 64 bit integers
that can and will be used in math operations and passed around. And we
don't have the "unsigned int".Use of unsigned int8 for ID makes sense almost always if database supports
it.
I may do such mistake even if I know I should use "string" (or "numeric")
for record IDs once I
start using type hints.Okay, we have GMP. I will have to use it. But let me just ask - if I work
with a DB handling 64 bit integers (all I know handle them) or use a
DECIMAL field - automaticly use GMP then? Oh gosh....I'm planning to introduce type affinity like SQLite. Then appropriate
types for the value may
be used automatically/semi-automatically. It's good for both security and
performance.Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Great! A Class or RFC that defined types that mapped one to one to DB types
sounds useful.
But this is not the same thing as generic pseudo type that are little more
that predefined regexs applied to strings (a.k.a the numeric type).
Walter
--
The greatest dangers to liberty lurk in insidious encroachment by men of
zeal, well-meaning but without understanding. -- Justice Louis D. Brandeis
Hi Stas,
On Thu, Apr 30, 2015 at 2:42 PM, Stanislav Malyshev smalyshev@gmail.com
wrote:
"int" Cast is bad. Incorrect "int" type hint worse as it could trigger
DoS.I do not see any potential for DoS here. Trying to assign security
implications so it looks like disagreeing with you jeopardizes security
is not a good idea. If your code accepts non-numeric data and puts it to
functions that except integers without validation, it is bad code and
"numeric" hint would not help here, as unvalidated data can contain
anything. If unexpected input causes denial of service in your code, it
is a code architecture problem, which should not be solved by adding
stuff to PHP.
I fully agree that all inputs must be validated before using for any
purpose
and I always suggest users to do that.
Unfortunately, not all users does this and new PHP type hint opens new hole
that security researchers and attackers are interested in.
filter_var()
can be used, but it's limited to CPU architecture...
It's one of the reason why I'm proposing Type Affinity like SQLite.
(I won't convert huge int to float, though. Another reason is performance.)
It's not all, but the main issue here is 32 bit CPU & PHP int is too
small for
database record IDs.Correct way to go there is treating these IDs as strings or objects and
having code that handles them properly. If they do not fit PHP int, they
should not be used with functions that expect int.
I fully agree that user must not use int/float type hints that exceeds PHP
limits.
That's the reason why I proposed pseudo "numeric" type in first place.
To maximize compatibility, arbitrarily size of int/float like
string/value should be
accepted as numeric(or int/float).No, it should not be, since they are neither int nor float.
I prefer relaxed int/float type hint a lot, but "numeric" can be
alternative.
It's much easier users to advocate "Use numeric type hint for database
record ID/etc", rather than "Use string type hint for database and
validate
it's content by yourself".
PHP were weakly typed and too strict type hint creates issue. Weakening
a bit does not harm any, narrowing window to attack. If user needs native
int/float strictly, they should/can use "strict" mode also.
Do you see issues with relaxing?
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi!
Unfortunately, not all users does this and new PHP type hint opens new hole
that security researchers and attackers are interested in.
I am sorry, but you still brought no proof at all that there are any
security implications. Without such proof, these claims are baseless, so
I intend to ignore them from now until such time as some proof would be
provided, and advise others to do the same.
I prefer relaxed int/float type hint a lot, but "numeric" can be
alternative.
No, it can't, because it's not a type, it's string regex check, and we
should not mix those with types.
It's much easier users to advocate "Use numeric type hint for database
record ID/etc", rather than "Use string type hint for database and
validate
it's content by yourself".
The latter is the right thing to do (well, except for the part where
string type is not really necessary unless you expect to get something
that can't be made string, in which case your code is very messed up by
that point).
PHP were weakly typed and too strict type hint creates issue. Weakening
a bit does not harm any, narrowing window to attack. If user needs native
There's no attack, and it does harm the design of the language by mixing
types with unrelated string regex checks.
int/float strictly, they should/can use "strict" mode also.
Do you see issues with relaxing?
Yes, lots of them.
--
Stas Malyshev
smalyshev@gmail.com
Hi Yasuo,
Am 30.04.2015 um 07:26 schrieb Yasuo Ohgaki:
"int" Cast is bad. Incorrect "int" type hint worse as it could trigger DoS.
could you please stop arguing with "Denial of Service" for this
behavior? Using a security related term that has nothing to do with the
actual problem is irritating. Using a 32bit machine and producing an
overflow which gracefully aborts your program (by a fatal error or an
exception) is no security issue. It is just a programming error.
Thanks
Dennis
Yasuo Ohgaki wrote:
On Thu, Apr 30, 2015 at 8:24 AM, Stanislav Malyshev smalyshev@gmail.com
wrote:PHP types are not machine native types. But yes, it forces PHP type -
that's why it is type check.Type hint is better to stay as "hint" under weak mode. IMO.
"Type hints" have never been hints. The wording is a misnomer. Try to
pass an int to a parameter declared as array, for instance.
You are saying type checking which produces fatal errors does not match
your use case. OK, I can sympathize, but how introducing more
pseudo-types helps? You just fix one narrow use case that you have right
now while leaving the problem still in the same place. That's not a good
way to address it.I'm not concerning myself, but I'm worrying about users to write
apps/libraries
that can cause DoS easily. I don't want to see my my apps emit fatal error
by upgrading library just because library author decided to use type hint
wrongly.
A fatal error wouldn't constitute a DoS vulnerability, would it?
BTW, GMP integer is already integrated into PHP why not treat GMP as int?
It's type "hint", isn't it?
The basic idea of the STHs is to guarantee that the value is of the
respective type inside the function (parameter type "hints") resp. the
return value (return value type "hints") has the respective type.
Accepting GMP for int just won't fit to this definition -- or it would
lead to a potentially considerable data loss.
--
Christoph M. Becker
Hi Christoph,
On Thu, Apr 30, 2015 at 8:24 AM, Stanislav Malyshev <smalyshev@gmail.com
wrote:
PHP types are not machine native types. But yes, it forces PHP type -
that's why it is type check.Type hint is better to stay as "hint" under weak mode. IMO.
"Type hints" have never been hints. The wording is a misnomer. Try to
pass an int to a parameter declared as array, for instance.
I understand how it worked and how it will.
"hint" sounds a little misleading. Since we named it already, we may follow
the semantics.
You are saying type checking which produces fatal errors does not match
your use case. OK, I can sympathize, but how introducing more
pseudo-types helps? You just fix one narrow use case that you have right
now while leaving the problem still in the same place. That's not a good
way to address it.I'm not concerning myself, but I'm worrying about users to write
apps/libraries
that can cause DoS easily. I don't want to see my my apps emit fatal
error
by upgrading library just because library author decided to use type hint
wrongly.A fatal error wouldn't constitute a DoS vulnerability, would it?
Attacker may inject huge ID value and/or they may simply access
web sites to reach 2 billion limit, for example.
BTW, GMP integer is already integrated into PHP why not treat GMP as int?
It's type "hint", isn't it?The basic idea of the STHs is to guarantee that the value is of the
respective type inside the function (parameter type "hints") resp. the
return value (return value type "hints") has the respective type.Accepting GMP for int just won't fit to this definition -- or it would
lead to a potentially considerable data loss.
I mean accept GMP as PHP int in weak mode as it is, not converting C int.
Strictly speaking GMP has its type, but it can be used as "string integer"
now.
i.e. $gmp_int_a + $gmp_int_b works just like $str_int_a + $str_int_b.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
"Type hints" have never been hints. The wording is a misnomer. Try to
pass an int to a parameter declared as array, for instance.I understand how it worked and how it will.
"hint" sounds a little misleading. Since we named it already, we may follow
the semantics.
Or, since we chose the semantics already, we may consider better names
(see on-going discussion on PHP-DOC list, for example).
A fatal error wouldn't constitute a DoS vulnerability, would it?
Attacker may inject huge ID value and/or they may simply access
web sites to reach 2 billion limit, for example.
That's not a DoS vector unless you've also done something else wrong,
it's just an embarassing error like many others. A lot of the time, the
DB will overflow first anyway, because an SQL "int" is signed 32-bit.
Hell, YouTube had a 32-bit int for number of views until Gangnam Style
overflowed it!
Sure, if a user can somehow insert custom data into a BigInt DB column,
via a 32-bit webserver, without causing the error on the way in, but in
such a way that other users would end up retrieving that record when
they tried to access the site, and it was then run through a function
with an "int" type annotation you'd have a Denial of Service. That's
hardly "PHP 7 broke my website", though.
Regards,
--
Rowan Collins
[IMSoP]
Hi Rowan,
On Thu, Apr 30, 2015 at 11:00 AM, Rowan Collins rowan.collins@gmail.com
wrote:
"Type hints" have never been hints. The wording is a misnomer. Try to
pass an int to a parameter declared as array, for instance.
I understand how it worked and how it will.
"hint" sounds a little misleading. Since we named it already, we may
follow
the semantics.Or, since we chose the semantics already, we may consider better names
(see on-going discussion on PHP-DOC list, for example).
I noticed that.
Type hint became "hint" actually by PHP7 because it convert string/float to
int, for example. IMHO.
A fatal error wouldn't constitute a DoS vulnerability, would it?
Attacker may inject huge ID value and/or they may simply access
web sites to reach 2 billion limit, for example.That's not a DoS vector unless you've also done something else wrong, it's
just an embarassing error like many others. A lot of the time, the DB will
overflow first anyway, because an SQL "int" is signed 32-bit. Hell, YouTube
had a 32-bit int for number of views until Gangnam Style overflowed it!
Not really. Primary key is out of user control almost always. However,
suppose code allows to specify foreign key and code assumes that non
existing foreign key results in search query failure.
Current PHP: Search query failure.
New PHP type hint: Fatal error because foreign key is out of PHP int range.
If user are using type hints everywhere, it may be limited to attackers
seeing fatal errors. If not, attacker can succeed system wide DoS attack by
simple operation.
Sure, if a user can somehow insert custom data into a BigInt DB column,
via a 32-bit webserver, without causing the error on the way in, but in
such a way that other users would end up retrieving that record when they
tried to access the site, and it was then run through a function with an
"int" type annotation you'd have a Denial of Service. That's hardly "PHP 7
broke my website", though.
There are systems that has "32 bit PHP client that queries 64 bit server".
Many IoT devices will stick to 32 bit CPUs.
Current PHP: Database ID is string and it works for any value.
New PHP type hint: Fatal error for values beyond PHP int range.
There are IoT devices that can be controlled by PHP already. We don't have
to limit ourselves.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Rowan,
A fatal error wouldn't constitute a DoS vulnerability, would it?
Attacker may inject huge ID value and/or they may simply access
web sites to reach 2 billion limit, for example.That's not a DoS vector unless you've also done something else wrong,
it's just an embarassing error like many others. A lot of the time, the DB
will overflow first anyway, because an SQL "int" is signed 32-bit. Hell,
YouTube had a 32-bit int for number of views until Gangnam Style overflowed
it!Not really. Primary key is out of user control almost always. However,
suppose code allows to specify foreign key and code assumes that non
existing foreign key results in search query failure.Current PHP: Search query failure.
New PHP type hint: Fatal error because foreign key is out of PHP int range.If user are using type hints everywhere, it may be limited to attackers
seeing fatal errors. If not, attacker can succeed system wide DoS attack by
simple operation.
I should have mentioned that I'm supposing DBMS like SQLite here.
As we know, SQLite column accepts any value including value beyond 64 bit
int.
https://www.sqlite.org/datatype3.html
(Those who don't now "Type Affinity", please read the section)
SQLite is the most used RDBMS in the world.
MySQL supports unsigned 64 bit integer also, BTW.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Rowan,
A fatal error wouldn't constitute a DoS vulnerability, would it?
Attacker may inject huge ID value and/or they may simply access
web sites to reach 2 billion limit, for example.That's not a DoS vector unless you've also done something else wrong,
it's just an embarassing error like many others. A lot of the time, the
DB
will overflow first anyway, because an SQL "int" is signed 32-bit. Hell,
YouTube had a 32-bit int for number of views until Gangnam Style
overflowed
it!Not really. Primary key is out of user control almost always. However,
suppose code allows to specify foreign key and code assumes that non
existing foreign key results in search query failure.Current PHP: Search query failure.
New PHP type hint: Fatal error because foreign key is out of PHP int
range.If user are using type hints everywhere, it may be limited to attackers
seeing fatal errors. If not, attacker can succeed system wide DoS attack
by
simple operation.I should have mentioned that I'm supposing DBMS like SQLite here.
As we know, SQLite column accepts any value including value beyond 64 bit
int.https://www.sqlite.org/datatype3.html
(Those who don't now "Type Affinity", please read the section)SQLite is the most used RDBMS in the world.
MySQL supports unsigned 64 bit integer also, BTW.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Are you asking to have both the 32 and 64 bit versions of PHP fully map to
the type system in SQLite? The type system in SQLite appears to have been
setup to map to programming language that lots of types (modern C, C++,
maybe Java) rather than PHP.
I think you might have an easier time fixing the SQLite adaptor for PHP
than making both 32 and 64 bit PHP map to the type structure for SQLite
completely transparently with full type defs.
--
The greatest dangers to liberty lurk in insidious encroachment by men of
zeal, well-meaning but without understanding. -- Justice Louis D. Brandeis
Hi Walter,
Are you asking to have both the 32 and 64 bit versions of PHP fully map to
the type system in SQLite? The type system in SQLite appears to have been
setup to map to programming language that lots of types (modern C, C++,
maybe Java) rather than PHP.I think you might have an easier time fixing the SQLite adaptor for PHP
than making both 32 and 64 bit PHP map to the type structure for SQLite
completely transparently with full type defs.
It's not a SQLite/etc access library issue, but the user code issue.
Average PHP users will use int type hint for record IDs. This results in
fatal
error (or exception). These code does not have to be my/your code, but
other libraries written by someone else.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Walter,
Are you asking to have both the 32 and 64 bit versions of PHP fully map
to the type system in SQLite? The type system in SQLite appears to have
been setup to map to programming language that lots of types (modern C,
C++, maybe Java) rather than PHP.I think you might have an easier time fixing the SQLite adaptor for PHP
than making both 32 and 64 bit PHP map to the type structure for SQLite
completely transparently with full type defs.It's not a SQLite/etc access library issue, but the user code issue.
Average PHP users will use int type hint for record IDs. This results in
fatal
error (or exception). These code does not have to be my/your code, but
other libraries written by someone else.Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Then this is exactly why we need type hints. If the average user is using
32 ints to map to 64 bit values, then someone has written broken code. The
code should fail with a type check error, not be automagically fixed if you
are using types. At some point the programmer should take responsibility
for matching the DB API to the code base. Hiding mistakes only sets up the
uninformed users for mistakes later.
Mixing 32 bit code/sizes with 64 code/sizes requires that you pay some
attention to sizes. Do everything in 32 bit, not a problem. Do everything
in 64 bit, not a problem. Mix the two and there is a cost. As far as a I
can tell, they is little desire in the current day to make the 32/64 hybrid
modes easier/simpler. This is a fact that people will have live with (or do
the work themselves). I see it as a legacy issue that is becoming more and
more irrelevant.
It would be nice to help, but it may setup future legacy issues that we
would rather not support.
Walter
--
The greatest dangers to liberty lurk in insidious encroachment by men of
zeal, well-meaning but without understanding. -- Justice Louis D. Brandeis
Hi Rowan,
A fatal error wouldn't constitute a DoS vulnerability, would it?
Attacker may inject huge ID value and/or they may simply access
web sites to reach 2 billion limit, for example.That's not a DoS vector unless you've also done something else wrong,
it's just an embarassing error like many others. A lot of the time, the
DB
will overflow first anyway, because an SQL "int" is signed 32-bit. Hell,
YouTube had a 32-bit int for number of views until Gangnam Style
overflowed
it!Not really. Primary key is out of user control almost always. However,
suppose code allows to specify foreign key and code assumes that non
existing foreign key results in search query failure.Current PHP: Search query failure.
New PHP type hint: Fatal error because foreign key is out of PHP int
range.
How is this different than other languages with type hint? For example,
Java or C# - if you type hint int you are limited to 32bit. These languages
have long and bigint respectively to support 64bit, but type hinting int
means you cannot have arbitrarily large numbers.
To me it sounds like you're trying to solve an application problem but
suggesting a change to the language.
If user are using type hints everywhere, it may be limited to attackers
seeing fatal errors. If not, attacker can succeed system wide DoS attack
by
simple operation.I should have mentioned that I'm supposing DBMS like SQLite here.
As we know, SQLite column accepts any value including value beyond 64 bit
int.
https://www.sqlite.org/datatype3.html
(Those who don't now "Type Affinity", please read the section)
From your link " The value is a signed integer, stored in 1, 2, 3, 4, 6,
or 8 bytes depending on the magnitude of the value." And take a look at
http://jakegoulding.com/blog/2011/02/06/sqlite-64-bit-integers/ where
numbers larger than the max are converted to real on storage sometimes,
depending on the affinity of the storage type chosen but not on math.
SQLite is the most used RDBMS in the world.
I would love to see some empirical data that supports this claim.
MySQL supports unsigned 64 bit integer also, BTW.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Ryan,
Hi Rowan,
On Thu, Apr 30, 2015 at 11:17 AM, Yasuo Ohgaki yohgaki@ohgaki.net
wrote:A fatal error wouldn't constitute a DoS vulnerability, would it?
Attacker may inject huge ID value and/or they may simply access
web sites to reach 2 billion limit, for example.That's not a DoS vector unless you've also done something else wrong,
it's just an embarassing error like many others. A lot of the time,
the DB
will overflow first anyway, because an SQL "int" is signed 32-bit.
Hell,
YouTube had a 32-bit int for number of views until Gangnam Style
overflowed
it!Not really. Primary key is out of user control almost always. However,
suppose code allows to specify foreign key and code assumes that non
existing foreign key results in search query failure.Current PHP: Search query failure.
New PHP type hint: Fatal error because foreign key is out of PHP int
range.How is this different than other languages with type hint? For example,
Java or C# - if you type hint int you are limited to 32bit. These languages
have long and bigint respectively to support 64bit, but type hinting int
means you cannot have arbitrarily large numbers.To me it sounds like you're trying to solve an application problem but
suggesting a change to the language.If user are using type hints everywhere, it may be limited to attackers
seeing fatal errors. If not, attacker can succeed system wide DoS
attack by
simple operation.I should have mentioned that I'm supposing DBMS like SQLite here.
As we know, SQLite column accepts any value including value beyond 64 bit
int.https://www.sqlite.org/datatype3.html
(Those who don't now "Type Affinity", please read the section)
From your link " The value is a signed integer, stored in 1, 2, 3, 4, 6,
or 8 bytes depending on the magnitude of the value." And take a look at
http://jakegoulding.com/blog/2011/02/06/sqlite-64-bit-integers/ where
numbers larger than the max are converted to real on storage sometimes,
depending on the affinity of the storage type chosen but not on math.
As PHP int type hint does not accept huge float as int, it does not matter,
does it?
<?php
function foo(int $v) {
echo $v;
}
foo('1.0e+33');
?>
Fatal error: Argument 1 passed to foo() must be of the type integer, string
given, called in - on line 6 and defined in - on line 2
SQLite is the most used RDBMS in the world.
I would love to see some empirical data that supports this claim.
You know number of mobile devices? All Android/iPhone have it.
Use of SQLite is not limited to phone, but almost every embedded device.
It's about PHP was and PHP currently is.
PHP didn't have any issues with huge record ID at all, but it can result
in DoS not limited to targeted, but including site wide. Bad news for me
is these DoS could be triggered by upgrade of library/etc that supports
PHP7 type hints, not the code that I've authored or supervised.
Anyway, too strict "weak" type hint cases problems any external inputs.
There should be a resolution.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Ryan,
On Wed, Apr 29, 2015 at 8:37 PM, Yasuo Ohgaki yohgaki@ohgaki.net
wrote:Hi Rowan,
On Thu, Apr 30, 2015 at 11:17 AM, Yasuo Ohgaki yohgaki@ohgaki.net
wrote:A fatal error wouldn't constitute a DoS vulnerability, would it?
Attacker may inject huge ID value and/or they may simply access
web sites to reach 2 billion limit, for example.That's not a DoS vector unless you've also done something else wrong,
it's just an embarassing error like many others. A lot of the time,
the DB
will overflow first anyway, because an SQL "int" is signed 32-bit.
Hell,
YouTube had a 32-bit int for number of views until Gangnam Style
overflowed
it!Not really. Primary key is out of user control almost always. However,
suppose code allows to specify foreign key and code assumes that non
existing foreign key results in search query failure.Current PHP: Search query failure.
New PHP type hint: Fatal error because foreign key is out of PHP int
range.How is this different than other languages with type hint? For example,
Java or C# - if you type hint int you are limited to 32bit. These
languages
have long and bigint respectively to support 64bit, but type hinting int
means you cannot have arbitrarily large numbers.To me it sounds like you're trying to solve an application problem but
suggesting a change to the language.If user are using type hints everywhere, it may be limited to
attackers
seeing fatal errors. If not, attacker can succeed system wide DoS
attack by
simple operation.I should have mentioned that I'm supposing DBMS like SQLite here.
As we know, SQLite column accepts any value including value beyond 64
bit
int.https://www.sqlite.org/datatype3.html
(Those who don't now "Type Affinity", please read the section)
From your link " The value is a signed integer, stored in 1, 2, 3, 4, 6,
or 8 bytes depending on the magnitude of the value." And take a look at
http://jakegoulding.com/blog/2011/02/06/sqlite-64-bit-integers/ where
numbers larger than the max are converted to real on storage sometimes,
depending on the affinity of the storage type chosen but not on math.As PHP int type hint does not accept huge float as int, it does not matter,
does it?<?php
function foo(int $v) {
echo $v;
}foo('1.0e+33');
?>Fatal error: Argument 1 passed to foo() must be of the type integer, string
given, called in - on line 6 and defined in - on line 2SQLite is the most used RDBMS in the world.
I would love to see some empirical data that supports this claim.
You know number of mobile devices? All Android/iPhone have it.
Use of SQLite is not limited to phone, but almost every embedded device.It's about PHP was and PHP currently is.
PHP didn't have any issues with huge record ID at all, but it can result
in DoS not limited to targeted, but including site wide. Bad news for me
is these DoS could be triggered by upgrade of library/etc that supports
PHP7 type hints, not the code that I've authored or supervised.Anyway, too strict "weak" type hint cases problems any external inputs.
There should be a resolution.Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
And that is relevant how? How many Android phone run PHP applications?
How many embedded devices of this type run PHP? If you are running a 64 bit
DB and a 32 bit PHP, change one to the other size or pay attention to your
sizes. Or stop using code from people that don't care to program correctly.
I'm sure I could find half a dozen metrics to make something else number
one (I'd put flat files at 1, a Mainframe DB at 2, and some PC db at 3).
Or just live with the fact that it not reasonable to expect that the system
will handle all of type checking for you without people having to think how
to refactor code to include type hints.
The resolution is simple, check your data before you hand it to third
parties if you don't trust them. Use unit and integration tests to alert
you for libraries where this might occur.
Walter
The greatest dangers to liberty lurk in insidious encroachment by men of
zeal, well-meaning but without understanding. -- Justice Louis D. Brandeis
Hi Walter,
And that is relevant how? How many Android phone run PHP applications?
Search web for IoT devices that can run PHP.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Walter,
And that is relevant how? How many Android phone run PHP applications?
Search web for IoT devices that can run PHP.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
You didn't answer the question: why should we care? Is there enough of user
base now to care? IOT might be able to run PHP, but how many actually do?
And of the ones that do, is automatically half fixing the code that bad
programmers might write for the last remaining 32 bit platforms a good use
of our time?
I don't see the numeric type as fixing any of these problems...
Walter
--
The greatest dangers to liberty lurk in insidious encroachment by men of
zeal, well-meaning but without understanding. -- Justice Louis D. Brandeis
Hi Walter,
You didn't answer the question: why should we care? Is there enough of
user base now to care? IOT might be able to run PHP, but how many actually
do? And of the ones that do, is automatically half fixing the code that bad
programmers might write for the last remaining 32 bit platforms a good use
of our time?
I don't suppose anyone objects view that IoT will be a big market in near
future.
The main problem is not only code IoT developers write, but libraries used
by them.
If you know embedded devices, they care every single dollar costs. I don't
see
any reason that they use 64 bit CPUs while 32 bit CPU is enough.
We may say using PHP and it's library is not safe, so don't use it.
I just don't like to say or anyone else say this.
I don't see the numeric type as fixing any of these problems...
Which is easier to advocate?
- Use "string" type hints for record ID/etc and validate value by yourself.
- Use "numeric" type hints for record ID/etc.
or even - Use weak mode "int" type hints (If it's relaxed)
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Walter,
You didn't answer the question: why should we care? Is there enough of
user base now to care? IOT might be able to run PHP, but how many actually
do? And of the ones that do, is automatically half fixing the code that bad
programmers might write for the last remaining 32 bit platforms a good use
of our time?I don't suppose anyone objects view that IoT will be a big market in near
future.
The main problem is not only code IoT developers write, but libraries used
by them.
If you know embedded devices, they care every single dollar costs. I don't
see
any reason that they use 64 bit CPUs while 32 bit CPU is enough.We may say using PHP and it's library is not safe, so don't use it.
I just don't like to say or anyone else say this.I don't see the numeric type as fixing any of these problems...
Which is easier to advocate?
- Use "string" type hints for record ID/etc and validate value by
yourself.- Use "numeric" type hints for record ID/etc.
or even- Use weak mode "int" type hints (If it's relaxed)
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
I didn't says there wouldn't be big. I think they could be giant. What I
said is that I think you are trying to solve a 1% edge problem that might
not be much of an issue when the are bigger problems and better solutions.
In an IOT where cost matter, using PHP is usually a poor design decision.
There are better languages. If costs matter, use the proper language for
this sort of environment (or use PHP correctly). I do not accept the
argument that we must use 32 bit CPUs and 32 bit PHP, but then go and use a
64 bit DB. Use a 32 bit DB, or restrict your self to 31 bit keys (or just
use strings). How many IOT systems use a language like PHP and not some
simplified system (picoBasic, microJava). I've worked on embedded systems.
When I worked with real world, cost sensitive systems, we used C, or a
stripped down language. Not a language like PHP. Note, Android uses Davik
(Java) or C/C++. iOS uses Objective-C, Windows Phone uses C#. All compiled
languages with mostly static type systems that map to the type systems of
the DB using a richer set of native types. PHP is not in a race to spread
to any and all platforms, regardless of suitability. Let's use the right
tools for the job.
You do know that you that can control the schema of the DB. Have you
suggested to SQLite that they make the default schemas PHP safe (instead of
making PHP SQLite safe). Why should PHP dance to SQLite's tune rather than
SQLite dancing to PHP's tune? I know this is a PHP mailing list, but PHP is
not the end all, be all of programming languages and anybody programming
IOT devices should know that. I'd prefer not to mess up PHP for its primary
market while trying to fix side issues for secondary targets.
I thing using string type hints are are easier to advocate (and I think
they are the correct type if you need to be 32/64 indepentent).
Otherwise, a numeric type doesn't fix the problem. It hides it. It is a
short term that doesn't scale properly.
Use int hints correctly. There are still new, if we start using the
incorrectly, things will only get worse.
Good night.
--
The greatest dangers to liberty lurk in insidious encroachment by men of
zeal, well-meaning but without understanding. -- Justice Louis D. Brandeis
I thing using string type hints are are easier to advocate (and I think
they are the correct type if you need to be 32/64 indepentent).
Otherwise, a numeric type doesn't fix the problem. It hides it. It is a
short term that doesn't scale properly.Use int hints correctly. There are still new, if we start using the
incorrectly, things will only get worse.
The drive by the 'strict' camp to get strict type checking in by any
means did mess up the discussion on the full implications of what weak
typing fall back was going to provide, so to be honest I see little
point in even allowing hinting in my tool set. I still need all of the
PHP5 type checking so why not simply maintain that? But now also having
to cope with additional platform differences :(
A number of areas of hinting are not supported, leaving what we now have
for PHP7. The result is less than satisfactory and this is a perfect
example! WHY am I restricted to using 'string' for the very thing that I
am working with mainly? The whole point with going to 64bit was to
properly support 64bit integers, but in an ideal world that would also
work on 32bit platforms ... transparently!
There are a number of different requirements all being pushed and the
result is we don't have an agreed roadmap. BIGINT is a case in point,
since it is either '64bit integer' or 'unlimited integer' and the two
are mutually exclusive. 32bit platforms NEED a reliable 64bit integer
moving forward, but some people seem to think that 32bit PHP can be
ignored? If I'm having to drop back to validating all the database data
as string values then what is the point of integer hints?
Some additional hints will be required in the future, and making
'numeric' an unlimited number makes sense if 'float' and 'int' are
restricted to some hardware limit, but additional fixed length hints
still makes perfect sense?
--
Lester Caine - G8HFL
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk
Current PHP: Search query failure.
New PHP type hint: Fatal error because foreign key is out of PHP int range.
There may be some confusion; NikiC is still doing some work to tidy up
the EngineExceptions. When that is finished passing a variable of the
wrong type will give a TypeException.
If user are using type hints everywhere, it may be limited to attackers
seeing fatal errors. If not, attacker can succeed system wide DoS attack by
simple operation.
Passing in invalid primary keys should never result in a DoS
attack...and I have no idea why you think it would be due to the
presence or absence of scalar type hints.
Yasuo wrote:
How many of us are expected that
mydb_find_by_id(INT_MAX+1);
Note: INT_MAX+1 is pseudo integer string value.
Well currently it isn't:
var_dump(PHP_INT_MAX + 1);
float(9.2233720368548E+18)
Yasuo wrote:
How about have "numeric" type hint that accepts any format/class(GMP)
of numeric values?The issue is that weak mode type hint is not weak at all. It forces to
have machine native type rather than it's data form.
So what you're suggesting is adding a numeric type that acts like GMP
and allow arbitrary precision arithmetic on values? Isn't that just
GMP? Except you'd need to convert the variable to be 'numeric' before
doing any operation on it i.e. something like:
$x = (numeric)INT_MAX;
mydb_find_by_id($x+1);
Unless you're also suggesting replacing PHP's current maths operations...
cheers
Dan
Dan,
On Thu, Apr 30, 2015 at 12:02 PM, Dan Ackroyd danack@basereality.com
wrote:
Current PHP: Search query failure.
New PHP type hint: Fatal error because foreign key is out of PHP int
range.There may be some confusion; NikiC is still doing some work to tidy up
the EngineExceptions. When that is finished passing a variable of the
wrong type will give a TypeException.If user are using type hints everywhere, it may be limited to attackers
seeing fatal errors. If not, attacker can succeed system wide DoS attack
by
simple operation.Passing in invalid primary keys should never result in a DoS
attack...and I have no idea why you think it would be due to the
presence or absence of scalar type hints.
It's very simple. PHP int can be smaller than DBMS's int.
With type hints, valid ID can cause fatal error.
Yasuo wrote:
How many of us are expected that
mydb_find_by_id(INT_MAX+1);
Note: INT_MAX+1 is pseudo integer string value.Well currently it isn't:
var_dump(PHP_INT_MAX + 1);
float(9.2233720368548E+18)
You should realize that DBMS returns values as strings. Record ID included,
of course.
Yasuo wrote:
How about have "numeric" type hint that accepts any format/class(GMP)
of numeric values?The issue is that weak mode type hint is not weak at all. It forces to
have machine native type rather than it's data form.So what you're suggesting is adding a numeric type that acts like GMP
and allow arbitrary precision arithmetic on values? Isn't that just
GMP? Except you'd need to convert the variable to be 'numeric' before
doing any operation on it i.e. something like:$x = (numeric)INT_MAX;
mydb_find_by_id($x+1);Unless you're also suggesting replacing PHP's current maths operations...
Have you ever try to change record ID supplied by DBMS? I guess not.
In this case, IDs are integer like string and it works perfectly regardless
of PHP int type.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
De : yohgaki@gmail.com [mailto:yohgaki@gmail.com] De la part de Yasuo
OhgakiExternal data can have any form of numbers.
Current PHP can handle them as "string". However PHP7's type hint cannot
handle numeric data well because it only has "int" and "float" hints.
I don't understand the error message. PHP 7 is supposed to accept numeric strings for 'int'. Is it too big for an int ? In this case, it is a conversion failure, the error message is wrong and should be replaced. About 32/64 bit integers, this is another subject that was partially hidden, as many others, by the STH war.
Regards
François
Hi Francois,
On Wed, Apr 29, 2015 at 7:03 PM, François Laupretre francois@php.net
wrote:
De : yohgaki@gmail.com [mailto:yohgaki@gmail.com] De la part de Yasuo
OhgakiExternal data can have any form of numbers.
Current PHP can handle them as "string". However PHP7's type hint cannot
handle numeric data well because it only has "int" and "float" hints.I don't understand the error message. PHP 7 is supposed to accept numeric
strings for 'int'. Is it too big for an int ? In this case, it is a
conversion failure, the error message is wrong and should be replaced.
About 32/64 bit integers, this is another subject that was partially
hidden, as many others, by the STH war.
Allowing any forms of int/float as string(and GMP) for weak mode int/float
type hint
would be alternative resolution for this issue. I think it's better than
"numeric" type
hint.
It seems current weak/strict type hint difference is
- weak: allow conversion, force the type
- strict: not allow conversion, force the type
If weak mode allows this
function foo(int $val) {
// $val became "int" if value fits for int
// otherwise "integer string" or "gmp" object accepted
// anything else is error
}
issue is resolved.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Francois,
Allowing any forms of int/float as string(and GMP) for weak mode int/float
type hint
would be alternative resolution for this issue. I think it's better than
"numeric" type
hint.It seems current weak/strict type hint difference is
- weak: allow conversion, force the type
- strict: not allow conversion, force the type
If weak mode allows this
function foo(int $val) {
// $val became "int" if value fits for int
// otherwise "integer string" or "gmp" object accepted
// anything else is error
}
I forgot to mention float. 32 bit machines uses float as int extensively.
So it should be
function foo(int $val) {
// $val became "int" if value fits for int
// (allow float value that is integer form)
// otherwise "integer string" or "gmp" object accepted
// anything else is error
}
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
This numeric type is a type of int or float. There is a formal name
for such types: union types. Some languages have syntax for union
types that would look like this: int | float. I have a draft RFC for
this subject: https://wiki.php.net/rfc/union_types. Union types would
be useful for other common cases as well, such as Foo | null
or
array | Traversable
.
This numeric type is a type of int or float. There is a formal name
for such types: union types. Some languages have syntax for union
types that would look like this: int | float. I have a draft RFC for
this subject: https://wiki.php.net/rfc/union_types. Union types would
be useful for other common cases as well, such asFoo | null
or
array | Traversable
.--
Yes, this a union type. As I understand the request, the union type
definition would look like int|float| string where is_numeric(string) is
true. According to the definition of is_numeric, it does not check to see
if the string can be cast into an int or float, only that it could parsed
an stuffed into a bignum or GMP object.
Walter
--
The greatest dangers to liberty lurk in insidious encroachment by men of
zeal, well-meaning but without understanding. -- Justice Louis D. Brandeis
Hi all,
External data can have any form of numbers.
Current PHP can handle them as "string". However PHP7's type hint cannot
handle numeric data well because it only has "int" and "float" hints.There are cases that programmer want/need to handle any numeric values.
e.g. JSON numeric, Database numeric, PHP's array key beyonds INT min/max,
Values for BCMath/GMP, etc. It's common for 32 bit platforms. For example,
we cannot do query database safely with "int" type hint.e.g.
function get_some_db_record(int $id) {}Most databases uses 64 bit signed int for database IDs, but this code
limits
$id to 32 bit signed int for 32 bit platforms. There are databases that
allow
unsigned 64 bit int ID.To avoid this problem, users must use "string" type hint and have to
validate
parameter by themselves. This ruins benefits of type hint. Most PHP will
not
use "string" type hint even if apps need large numbers.How about have "numeric" type hint that accepts any format/class(GMP)
of numeric values?function foo(numeric $var) { // do something useful with numeric value }
To be honest, I would like to have StrictSTH RFC behavior for weak mode
int/float type hints to make sure "int"/"float" has integer/float
form/value always,
but "numeric" type hint may do the job. One function with "int"/"float"
type hint
could break app with current type hint implementation, though. i.e.
Working
app suddenly emits fatal error and exits when database/json returns value
beyond int/float.http://3v4l.org/6J0bZ (See how it works with large string integer value)
Any comments?
I've never wrote my blog in English, but I wrote one because peice by piece
discussion is not going to anywhere.
http://blog.ohgaki.net/dont-use-php7-type-hint-for-external-data
How many of you think current scalar type hint is useful enough to interact
with database/json/xml/yaml/rest/etc? We need "numeric" hint at least. IMHO.
If not, we need "large warning sign" in documentation as a last resort at
least.
Regards,
P.S. We may be better to declare 32 bit CPU support EOL by PHP 7 to reduce
the impact. We'll have the same issue when 128 bit CPU or 128 bits IEEE 754
float
became in common, though.
--
Yasuo Ohgaki
yohgaki@ohgaki.net
пн, 11 Май 2015, 10:21, Yasuo Ohgaki yohgaki@ohgaki.net:
Hi all,
I've never wrote my blog in English, but I wrote one because peice by piece
discussion is not going to anywhere.
http://blog.ohgaki.net/dont-use-php7-type-hint-for-external-data
How many of you think current scalar type hint is useful enough to interact
with database/json/xml/yaml/rest/etc? We need "numeric" hint at least. IMHO.
If not, we need "large warning sign" in documentation as a last resort at
least.
Regards,
P.S. We may be better to declare 32 bit CPU support EOL by PHP 7 to reduce
the impact. We'll have the same issue when 128 bit CPU or 128 bits IEEE 754
float
became in common, though.
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hello, I have read through your blog post, and I agreed on the issue
earlier, nut I have a question that bugs me for a while: what DoS issue are
you talking about? I tried to imagine any scenario that can lead to a DoS
wuith a type hint and can't think of any happening...
пн, 11 Май 2015, 10:21, Yasuo Ohgaki yohgaki@ohgaki.net:
Hi all,
I've never wrote my blog in English, but I wrote one because peice by
piece
discussion is not going to anywhere.http://blog.ohgaki.net/dont-use-php7-type-hint-for-external-data
How many of you think current scalar type hint is useful enough to
interact
with database/json/xml/yaml/rest/etc? We need "numeric" hint at least.
IMHO.If not, we need "large warning sign" in documentation as a last resort at
least.Regards,
P.S. We may be better to declare 32 bit CPU support EOL by PHP 7 to reduce
the impact. We'll have the same issue when 128 bit CPU or 128 bits IEEE
754
float
became in common, though.--
Yasuo Ohgaki
yohgaki@ohgaki.netHello, I have read through your blog post, and I agreed on the issue
earlier, nut I have a question that bugs me for a while: what DoS issue
are
you talking about? I tried to imagine any scenario that can lead to a DoS
wuith a type hint and can't think of any happening...
If any it is a bug in PHP, php driver or the likes.
About killing 32bit, why not, while there are still some needs for it. But
definitely not for this reason, which is totally unrelated.
Cheers,
Pierre
Hi Arvids,
On Mon, May 11, 2015 at 8:01 PM, Arvids Godjuks arvids.godjuks@gmail.com
wrote:
Hello, I have read through your blog post, and I agreed on the issue
earlier, nut I have a question that bugs me for a while: what DoS issue are
you talking about? I tried to imagine any scenario that can lead to a DoS
wuith a type hint and can't think of any happening...
Too large value raise typeException (Thanks Nikita)
DoS is easy on 32 bit CPU machines, but it's possible on 64 bit machines
also.
Simplest scenario would be client side DoS. Many IoT devices will remain 32
bits and if it
gets result value larger than 2 billions, execution may stopped by
unhandled exception
sudduly. Library/framework uses basic type hint may harm system like this.
Some databases support unsigned INT8. Most databases support NUMERIC/DECIMAL
which can have value larger signed 64 bit int. If attacker find way to
store too large ID
somewhere (e.g. as JSON/XML text that queries database), then system may
use the
value against type hinted functions/methods.
Without basic type hints, these concerns weren't existed.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Arvids,
On Mon, May 11, 2015 at 8:01 PM, Arvids Godjuks arvids.godjuks@gmail.com
wrote:Hello, I have read through your blog post, and I agreed on the issue
earlier, nut I have a question that bugs me for a while: what DoS issue are
you talking about? I tried to imagine any scenario that can lead to a DoS
wuith a type hint and can't think of any happening...Too large value raise typeException (Thanks Nikita)
DoS is easy on 32 bit CPU machines, but it's possible on 64 bit machines
also.Simplest scenario would be client side DoS. Many IoT devices will remain 32
bits and if it
gets result value larger than 2 billions, execution may stopped by
unhandled exception
sudduly. Library/framework uses basic type hint may harm system like this.Some databases support unsigned INT8. Most databases support NUMERIC/DECIMAL
which can have value larger signed 64 bit int. If attacker find way to
store too large ID
somewhere (e.g. as JSON/XML text that queries database), then system may
use the
value against type hinted functions/methods.Without basic type hints, these concerns weren't existed.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Yasuo,
I still don’t see how you can put the blame for the unhanded exception on type hints. The problem you’re describing is not new and exists today with libraries using code like this:
function foo($int) {
if(!is_int($int)) {
throw new InvalidArgumentException(‘Parameter must be of type int’);
}
//… do something with $int
}
Cheers,
David
Hi David,
I still don’t see how you can put the blame for the unhanded exception on
type hints. The problem you’re describing is not new and exists today with
libraries using code like this:function foo($int) {
if(!is_int($int)) {
throw new InvalidArgumentException(‘Parameter must be of type
int’);
}
//… do something with $int
}
Thoughtful/careful programmers will not have problems.
Programmers who assume old behavior with "int" hint will.
Sorry that I created scattered threads. I thought is_digists()/digits hint
might
be useful. Anyway it's from the other thread.
In PHP, integer like values are treated
signed 32 bit int: 32 bit CPU
signed 53 bit int: 32/64 bit CPU (IEEE 754 double)
signed 64 bit int: 64 bit CPU
arbitrarily int: 32/64 bit CPU (string digits is good enough for
databases/etc IDs)
If arithmetic is needed, we could assume it has at least signed 53 bit int.
If arithmetic is not needed, we could assume
arbitrarily int. I usually don't need integer arithmetic correctness much
because most arithmetic are very
simple. Examples are adding/subtracting date, stock, counter which will
never exceed signed 53 bit int range.
In contrast, I need strict correctness for record IDs. Valid IDs should
never raise error/exception.
Use of type "int" type hint reduces reliable range to signed 32 bit int.
We should have big warning in the manual so that users will not have wrong
assumption.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net