Skip to content

forbid cast as bool + forbid surrogate chars in strings #8980

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/libextra/ebml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ pub mod reader {
}

fn read_bool(&mut self) -> bool {
doc_as_u8(self.next_doc(EsBool)) as bool
doc_as_u8(self.next_doc(EsBool)) != 0
}

fn read_f64(&mut self) -> f64 {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2219,7 +2219,7 @@ pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) {
}
let v = ccx.const_values.get_copy(&item.id);
unsafe {
if !(llvm::LLVMConstIntGetZExtValue(v) as bool) {
if !(llvm::LLVMConstIntGetZExtValue(v) != 0) {
ccx.sess.span_fatal(expr.span, "static assertion failed");
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/librustc/middle/typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2696,6 +2696,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
}, t_e, None);
}

let t1 = structurally_resolved_type(fcx, e.span, t_1);
let te = structurally_resolved_type(fcx, e.span, t_e);
let t_1_is_char = type_is_char(fcx, expr.span, t_1);

Expand All @@ -2710,6 +2711,9 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
fmt!("only `u8` can be cast as `char`, not `%s`", actual)
}, t_e, None);
}
} else if ty::get(t1).sty == ty::ty_bool {
fcx.tcx().sess.span_err(expr.span,
"cannot cast as `bool`, compare with zero instead");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Cannot cast to bool"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really sure if to or as sounds nicer here, but I'm still leaning towards as.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, if someone feels strongly about it, they can come and change it later.

} else if type_is_region_ptr(fcx, expr.span, t_e) &&
type_is_unsafe_ptr(fcx, expr.span, t_1) {

Expand Down
15 changes: 12 additions & 3 deletions src/libstd/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,8 @@ pub fn is_utf8(v: &[u8]) -> bool {
// first C2 80 last DF BF
// 3-byte encoding is for codepoints \u0800 to \uffff
// first E0 A0 80 last EF BF BF
// excluding surrogates codepoints \ud800 to \udfff
// ED A0 80 to ED BF BF
// 4-byte encoding is for codepoints \u10000 to \u10ffff
// first F0 90 80 80 last F4 8F BF BF
//
Expand All @@ -812,8 +814,6 @@ pub fn is_utf8(v: &[u8]) -> bool {
// UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
// %xF4 %x80-8F 2( UTF8-tail )
// UTF8-tail = %x80-BF
// --
// This code allows surrogate pairs: \uD800 to \uDFFF -> ED A0 80 to ED BF BF
match w {
2 => if unsafe_get(v, i + 1) & 192u8 != TAG_CONT_U8 {
return false
Expand All @@ -822,7 +822,9 @@ pub fn is_utf8(v: &[u8]) -> bool {
unsafe_get(v, i + 1),
unsafe_get(v, i + 2) & 192u8) {
(0xE0 , 0xA0 .. 0xBF, TAG_CONT_U8) => (),
(0xE1 .. 0xEF, 0x80 .. 0xBF, TAG_CONT_U8) => (),
(0xE1 .. 0xEC, 0x80 .. 0xBF, TAG_CONT_U8) => (),
(0xED , 0x80 .. 0x9F, TAG_CONT_U8) => (),
(0xEE .. 0xEF, 0x80 .. 0xBF, TAG_CONT_U8) => (),
_ => return false,
},
_ => match (v_i,
Expand Down Expand Up @@ -3012,6 +3014,7 @@ mod tests {

#[test]
fn test_is_utf8() {
// deny overlong encodings
assert!(!is_utf8([0xc0, 0x80]));
assert!(!is_utf8([0xc0, 0xae]));
assert!(!is_utf8([0xe0, 0x80, 0x80]));
Expand All @@ -3020,9 +3023,15 @@ mod tests {
assert!(!is_utf8([0xf0, 0x82, 0x82, 0xac]));
assert!(!is_utf8([0xf4, 0x90, 0x80, 0x80]));

// deny surrogates
assert!(!is_utf8([0xED, 0xA0, 0x80]));
assert!(!is_utf8([0xED, 0xBF, 0xBF]));

assert!(is_utf8([0xC2, 0x80]));
assert!(is_utf8([0xDF, 0xBF]));
assert!(is_utf8([0xE0, 0xA0, 0x80]));
assert!(is_utf8([0xED, 0x9F, 0xBF]));
assert!(is_utf8([0xEE, 0x80, 0x80]));
assert!(is_utf8([0xEF, 0xBF, 0xBF]));
assert!(is_utf8([0xF0, 0x90, 0x80, 0x80]));
assert!(is_utf8([0xF4, 0x8F, 0xBF, 0xBF]));
Expand Down
12 changes: 12 additions & 0 deletions src/test/compile-fail/cast-as-bool.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// error-pattern: cannot cast as `bool`, compare with zero instead
fn main() { let u = (5 as bool); }
1 change: 0 additions & 1 deletion src/test/run-pass/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,5 @@ pub fn main() {
assert_eq!(i as u8, 'Q' as u8);
assert_eq!(i as u8 as i8, 'Q' as u8 as i8);
assert_eq!(0x51u8 as char, 'Q');
assert_eq!(true, 1 as bool);
assert_eq!(0 as u32, false as u32);
}
15 changes: 0 additions & 15 deletions src/test/run-pass/supported-cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ pub fn main() {
info!(1 as int);
info!(1 as uint);
info!(1 as float);
info!(1 as bool);
info!(1 as *libc::FILE);
info!(1 as i8);
info!(1 as i16);
Expand All @@ -42,7 +41,6 @@ pub fn main() {
info!(1u as int);
info!(1u as uint);
info!(1u as float);
info!(1u as bool);
info!(1u as *libc::FILE);
info!(1u as i8);
info!(1u as i16);
Expand All @@ -58,7 +56,6 @@ pub fn main() {
info!(1i8 as int);
info!(1i8 as uint);
info!(1i8 as float);
info!(1i8 as bool);
info!(1i8 as *libc::FILE);
info!(1i8 as i8);
info!(1i8 as i16);
Expand All @@ -74,7 +71,6 @@ pub fn main() {
info!(1u8 as int);
info!(1u8 as uint);
info!(1u8 as float);
info!(1u8 as bool);
info!(1u8 as *libc::FILE);
info!(1u8 as i8);
info!(1u8 as i16);
Expand All @@ -90,7 +86,6 @@ pub fn main() {
info!(1i16 as int);
info!(1i16 as uint);
info!(1i16 as float);
info!(1i16 as bool);
info!(1i16 as *libc::FILE);
info!(1i16 as i8);
info!(1i16 as i16);
Expand All @@ -106,7 +101,6 @@ pub fn main() {
info!(1u16 as int);
info!(1u16 as uint);
info!(1u16 as float);
info!(1u16 as bool);
info!(1u16 as *libc::FILE);
info!(1u16 as i8);
info!(1u16 as i16);
Expand All @@ -122,7 +116,6 @@ pub fn main() {
info!(1i32 as int);
info!(1i32 as uint);
info!(1i32 as float);
info!(1i32 as bool);
info!(1i32 as *libc::FILE);
info!(1i32 as i8);
info!(1i32 as i16);
Expand All @@ -138,7 +131,6 @@ pub fn main() {
info!(1u32 as int);
info!(1u32 as uint);
info!(1u32 as float);
info!(1u32 as bool);
info!(1u32 as *libc::FILE);
info!(1u32 as i8);
info!(1u32 as i16);
Expand All @@ -154,7 +146,6 @@ pub fn main() {
info!(1i64 as int);
info!(1i64 as uint);
info!(1i64 as float);
info!(1i64 as bool);
info!(1i64 as *libc::FILE);
info!(1i64 as i8);
info!(1i64 as i16);
Expand All @@ -170,7 +161,6 @@ pub fn main() {
info!(1u64 as int);
info!(1u64 as uint);
info!(1u64 as float);
info!(1u64 as bool);
info!(1u64 as *libc::FILE);
info!(1u64 as i8);
info!(1u64 as i16);
Expand All @@ -186,7 +176,6 @@ pub fn main() {
info!(1u64 as int);
info!(1u64 as uint);
info!(1u64 as float);
info!(1u64 as bool);
info!(1u64 as *libc::FILE);
info!(1u64 as i8);
info!(1u64 as i16);
Expand All @@ -202,7 +191,6 @@ pub fn main() {
info!(true as int);
info!(true as uint);
info!(true as float);
info!(true as bool);
info!(true as *libc::FILE);
info!(true as i8);
info!(true as i16);
Expand All @@ -218,7 +206,6 @@ pub fn main() {
info!(1. as int);
info!(1. as uint);
info!(1. as float);
info!(1. as bool);
info!(1. as i8);
info!(1. as i16);
info!(1. as i32);
Expand All @@ -233,7 +220,6 @@ pub fn main() {
info!(1f32 as int);
info!(1f32 as uint);
info!(1f32 as float);
info!(1f32 as bool);
info!(1f32 as i8);
info!(1f32 as i16);
info!(1f32 as i32);
Expand All @@ -248,7 +234,6 @@ pub fn main() {
info!(1f64 as int);
info!(1f64 as uint);
info!(1f64 as float);
info!(1f64 as bool);
info!(1f64 as i8);
info!(1f64 as i16);
info!(1f64 as i32);
Expand Down