[ 
https://issues.apache.org/jira/browse/THRIFT-5310?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17232637#comment-17232637
 ] 

Eric-Christian Koch commented on THRIFT-5310:
---------------------------------------------

Hello [~jensg],

thank you for your feedback!

I wouldn't call it "correct". While it is correct bit-wise, a -1 is still wrong 
for the receiver to work with, because it does not match the intention of the 
sender. 255 would ofc be wrong as well, since it should have never gone on the 
wire as i8. IMHO :)

I checked some more language libraries and it seems that all untyped languages 
do suffer from this. The languages, i took a quick peek at (except ruby), had 
no range checks at all. For strongly typed languages that is ofc no problem, 
but for the rest?

There are some optional type validations for the generated code, but they only 
check for the general type like "Is it an Integer?". Which is valid for i8 to 
i64, at least in ruby. 

Any advice on who i could poke? :)

 

Best Regards,
Eric

> Ruby BinaryProtocol has invalid range checks for byte and i64
> -------------------------------------------------------------
>
>                 Key: THRIFT-5310
>                 URL: https://issues.apache.org/jira/browse/THRIFT-5310
>             Project: Thrift
>          Issue Type: Bug
>          Components: Ruby - Library
>    Affects Versions: 0.13.0
>            Reporter: Eric-Christian Koch
>            Priority: Major
>
> Hello,
> The range checks in 
> [https://github.com/apache/thrift/blob/master/lib/rb/lib/thrift/protocol/binary_protocol.rb|https://github.com/apache/thrift/blob/master/lib/rb/lib/thrift/protocol/binary_protocol.rb#L85]
>  are wrong.
> Right now, if for example, someone accidentally writes an unsigned byte like 
> 255, it would read as -1 on the other end of the line.
>  
> For write_byte, it should be:
> {code:ruby}
>  byte < -2**7 || byte >= 2**7 {code}
> For write_i64, it should be:
> {code:ruby}
>  i64 < -2**63 || i64 >= 2**63 {code}
> And i just noticed that for write_i16 there is no range check at all.
>  
> It is probably also better to put the calculated min/max values into consts. 
> I did a quick benchmark:
> {noformat}
>                            user     system      total        real
> with const:            0.526762   0.000562   0.527324 (  0.528134)
> with calculation:      2.384387   0.002364   2.386751 (  2.389461){noformat}
> Here is the code:
> {code:ruby}
> require 'benchmark'
> MIN_I64 = -2**63
> MAX_I64 = 2**63 - 1
> def check_with_const(i64)
>   i64 < MIN_I64 || i64 > MAX_I64
> end
> def check_with_calc(i64)
>   i64 < -2**63 || i64 >= 2**63
> end
> n = 5_000_000
> Benchmark.bm(20) do |x|
>   x.report('with const:') { (1..n).each { |i|; check_with_const(i) } }
>   x.report('with calculation:') { (1..n).each { |i|; check_with_calc(i) } }
> end
> {code}
>  
> If PR's are welcome i'm more than happy to provide one. :)
>  
> Best regards,
>  Eric
>  
>  



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to