v/checker: Warn about pointer indexing outside unsafe {} (#5918)
							parent
							
								
									d46a89b90d
								
							
						
					
					
						commit
						ee349691f9
					
				|  | @ -86,7 +86,7 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool { | |||
| 	//////csymbols := backtrace_symbols(*voidptr(&buffer[skipframes]), nr_actual_frames)
 | ||||
| 	csymbols := C.backtrace_symbols(&buffer[skipframes], nr_actual_frames) | ||||
| 	for i in 0 .. nr_actual_frames { | ||||
| 		sframes << tos2( byteptr(csymbols[i]) ) | ||||
| 		sframes << unsafe {tos2( byteptr(csymbols[i]) )} | ||||
| 	} | ||||
| 	for sframe in sframes { | ||||
| 		executable := sframe.all_before('(') | ||||
|  |  | |||
|  | @ -84,10 +84,10 @@ fn (mut m SortedMap) set(key string, value voidptr) { | |||
| 				} | ||||
| 				return | ||||
| 			} | ||||
| 			node = if key < parent.keys[child_index] { | ||||
| 				&mapnode(parent.children[child_index]) | ||||
| 			if key < parent.keys[child_index] { | ||||
| 				node = unsafe {&mapnode(parent.children[child_index])} | ||||
| 			} else { | ||||
| 				&mapnode(parent.children[child_index + 1]) | ||||
| 				node = unsafe {&mapnode(parent.children[child_index + 1])} | ||||
| 			} | ||||
| 		} | ||||
| 		mut i := 0 | ||||
|  | @ -116,7 +116,7 @@ fn (mut m SortedMap) set(key string, value voidptr) { | |||
| 		} | ||||
| 		parent = node | ||||
| 		child_index = i | ||||
| 		node = &mapnode(node.children[child_index]) | ||||
| 		node = unsafe {&mapnode(node.children[child_index])} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -131,22 +131,30 @@ fn (mut n mapnode) split_child(child_index int, mut y mapnode) { | |||
| 	if !isnil(y.children) { | ||||
| 		z.children = &voidptr(malloc(int(children_bytes))) | ||||
| 		for jj := degree - 1; jj >= 0; jj-- { | ||||
| 			z.children[jj] = y.children[jj + degree] | ||||
| 			unsafe { | ||||
| 				z.children[jj] = y.children[jj + degree] | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	if isnil(n.children) { | ||||
| 		n.children = &voidptr(malloc(int(children_bytes))) | ||||
| 	} | ||||
| 	n.children[n.len + 1] = n.children[n.len] | ||||
| 	unsafe { | ||||
| 		n.children[n.len + 1] = n.children[n.len] | ||||
| 	} | ||||
| 	for j := n.len; j > child_index; j-- { | ||||
| 		n.keys[j] = n.keys[j - 1] | ||||
| 		n.values[j] = n.values[j - 1] | ||||
| 		n.children[j] = n.children[j - 1] | ||||
| 		unsafe { | ||||
| 			n.children[j] = n.children[j - 1] | ||||
| 		} | ||||
| 	} | ||||
| 	n.keys[child_index] = y.keys[mid_index] | ||||
| 	n.values[child_index] = y.values[mid_index] | ||||
| 	n.children[child_index] = voidptr(y) | ||||
| 	n.children[child_index + 1] = voidptr(z) | ||||
| 	unsafe { | ||||
| 		n.children[child_index] = voidptr(y) | ||||
| 		n.children[child_index + 1] = voidptr(z) | ||||
| 	} | ||||
| 	n.len++ | ||||
| } | ||||
| 
 | ||||
|  | @ -164,7 +172,7 @@ fn (m SortedMap) get(key string, out voidptr) bool { | |||
| 		if isnil(node.children) { | ||||
| 			break | ||||
| 		} | ||||
| 		node = &mapnode(node.children[i + 1]) | ||||
| 		node = unsafe {&mapnode(node.children[i + 1])} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | @ -183,7 +191,7 @@ fn (m SortedMap) exists(key string) bool { | |||
| 		if isnil(node.children) { | ||||
| 			break | ||||
| 		} | ||||
| 		node = &mapnode(node.children[i + 1]) | ||||
| 		node = unsafe {&mapnode(node.children[i + 1])} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | @ -210,15 +218,17 @@ fn (mut n mapnode) remove_key(k string) bool { | |||
| 			return false | ||||
| 		} | ||||
| 		flag := if idx == n.len {true} else {false} | ||||
| 		if (&mapnode(n.children[idx])).len < degree { | ||||
| 		if unsafe {&mapnode(n.children[idx])}.len < degree { | ||||
| 			n.fill(idx) | ||||
| 		} | ||||
| 
 | ||||
| 		mut node := &mapnode(0) | ||||
| 		if flag && idx > n.len { | ||||
| 			return (&mapnode(n.children[idx - 1])).remove_key(k) | ||||
| 			node = unsafe {&mapnode(n.children[idx - 1])} | ||||
| 		} else { | ||||
| 			return (&mapnode(n.children[idx])).remove_key(k) | ||||
| 			node = unsafe {&mapnode(n.children[idx])} | ||||
| 		} | ||||
| 		return node.remove_key(k) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -232,34 +242,37 @@ fn (mut n mapnode) remove_from_leaf(idx int) { | |||
| 
 | ||||
| fn (mut n mapnode) remove_from_non_leaf(idx int) { | ||||
| 	k := n.keys[idx] | ||||
| 	if &mapnode(n.children[idx]).len >= degree { | ||||
| 		mut current := &mapnode(n.children[idx]) | ||||
| 	if unsafe {&mapnode(n.children[idx])}.len >= degree { | ||||
| 		mut current := unsafe {&mapnode(n.children[idx])} | ||||
| 		for !isnil(current.children) { | ||||
| 			current = &mapnode(current.children[current.len]) | ||||
| 			current = unsafe {&mapnode(current.children[current.len])} | ||||
| 		} | ||||
| 		predecessor := current.keys[current.len - 1] | ||||
| 		n.keys[idx] = predecessor | ||||
| 		n.values[idx] = current.values[current.len - 1] | ||||
| 		(&mapnode(n.children[idx])).remove_key(predecessor) | ||||
| 	} else if &mapnode(n.children[idx + 1]).len >= degree { | ||||
| 		mut current := &mapnode(n.children[idx + 1]) | ||||
| 		node := unsafe {&mapnode(n.children[idx])} | ||||
| 		node.remove_key(predecessor) | ||||
| 	} else if unsafe {&mapnode(n.children[idx + 1])}.len >= degree { | ||||
| 		mut current := unsafe {&mapnode(n.children[idx + 1])} | ||||
| 		for !isnil(current.children) { | ||||
| 			current = &mapnode(current.children[0]) | ||||
| 			current = unsafe {&mapnode(current.children[0])} | ||||
| 		} | ||||
| 		successor := current.keys[0] | ||||
| 		n.keys[idx] = successor | ||||
| 		n.values[idx] = current.values[0] | ||||
| 		(&mapnode(n.children[idx + 1])).remove_key(successor) | ||||
| 		node := unsafe {&mapnode(n.children[idx + 1])} | ||||
| 		node.remove_key(successor) | ||||
| 	} else { | ||||
| 		n.merge(idx) | ||||
| 		(&mapnode(n.children[idx])).remove_key(k) | ||||
| 		node := unsafe {&mapnode(n.children[idx])} | ||||
| 		node.remove_key(k) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (mut n mapnode) fill(idx int) { | ||||
| 	if idx != 0 && &mapnode(n.children[idx - 1]).len >= degree { | ||||
| 	if idx != 0 && unsafe {&mapnode(n.children[idx - 1])}.len >= degree { | ||||
| 		n.borrow_from_prev(idx) | ||||
| 	} else if idx != n.len && &mapnode(n.children[idx + 1]).len >= degree { | ||||
| 	} else if idx != n.len && unsafe {&mapnode(n.children[idx + 1])}.len >= degree { | ||||
| 		n.borrow_from_next(idx) | ||||
| 	} else if idx != n.len { | ||||
| 		n.merge(idx) | ||||
|  | @ -269,21 +282,25 @@ fn (mut n mapnode) fill(idx int) { | |||
| } | ||||
| 
 | ||||
| fn (mut n mapnode) borrow_from_prev(idx int) { | ||||
| 	mut child := &mapnode(n.children[idx]) | ||||
| 	mut sibling := &mapnode(n.children[idx - 1]) | ||||
| 	mut child := unsafe {&mapnode(n.children[idx])} | ||||
| 	mut sibling := unsafe {&mapnode(n.children[idx - 1])} | ||||
| 	for i := child.len - 1; i >= 0; i-- { | ||||
| 		child.keys[i + 1] = child.keys[i] | ||||
| 		child.values[i + 1] = child.values[i] | ||||
| 	} | ||||
| 	if !isnil(child.children) { | ||||
| 		for i := child.len; i >= 0; i-- { | ||||
| 			child.children[i + 1] = child.children[i] | ||||
| 			unsafe { | ||||
| 				child.children[i + 1] = child.children[i] | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	child.keys[0] = n.keys[idx - 1] | ||||
| 	child.values[0] = n.values[idx - 1] | ||||
| 	if !isnil(child.children) { | ||||
| 		child.children[0] = sibling.children[sibling.len] | ||||
| 		unsafe { | ||||
| 			child.children[0] = sibling.children[sibling.len] | ||||
| 		} | ||||
| 	} | ||||
| 	n.keys[idx - 1] = sibling.keys[sibling.len - 1] | ||||
| 	n.values[idx - 1] = sibling.values[sibling.len - 1] | ||||
|  | @ -292,12 +309,14 @@ fn (mut n mapnode) borrow_from_prev(idx int) { | |||
| } | ||||
| 
 | ||||
| fn (mut n mapnode) borrow_from_next(idx int) { | ||||
| 	mut child := &mapnode(n.children[idx]) | ||||
| 	mut sibling := &mapnode(n.children[idx + 1]) | ||||
| 	mut child := unsafe {&mapnode(n.children[idx])} | ||||
| 	mut sibling := unsafe {&mapnode(n.children[idx + 1])} | ||||
| 	child.keys[child.len] = n.keys[idx] | ||||
| 	child.values[child.len] = n.values[idx] | ||||
| 	if !isnil(child.children) { | ||||
| 		child.children[child.len + 1] = sibling.children[0] | ||||
| 		unsafe { | ||||
| 			child.children[child.len + 1] = sibling.children[0] | ||||
| 		} | ||||
| 	} | ||||
| 	n.keys[idx] = sibling.keys[0] | ||||
| 	n.values[idx] = sibling.values[0] | ||||
|  | @ -307,7 +326,9 @@ fn (mut n mapnode) borrow_from_next(idx int) { | |||
| 	} | ||||
| 	if !isnil(sibling.children) { | ||||
| 		for i := 1; i <= sibling.len; i++ { | ||||
| 			sibling.children[i - 1] = sibling.children[i] | ||||
| 			unsafe { | ||||
| 				sibling.children[i - 1] = sibling.children[i] | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	child.len++ | ||||
|  | @ -315,8 +336,8 @@ fn (mut n mapnode) borrow_from_next(idx int) { | |||
| } | ||||
| 
 | ||||
| fn (mut n mapnode) merge(idx int) { | ||||
| 	mut child := &mapnode(n.children[idx]) | ||||
| 	sibling := &mapnode(n.children[idx + 1]) | ||||
| 	mut child := unsafe {&mapnode(n.children[idx])} | ||||
| 	sibling := unsafe {&mapnode(n.children[idx + 1])} | ||||
| 	child.keys[mid_index] = n.keys[idx] | ||||
| 	child.values[mid_index] = n.values[idx] | ||||
| 	for i in 0..sibling.len { | ||||
|  | @ -325,7 +346,9 @@ fn (mut n mapnode) merge(idx int) { | |||
| 	} | ||||
| 	if !isnil(child.children) { | ||||
| 		for i := 0; i <= sibling.len; i++ { | ||||
| 			child.children[i + degree] = sibling.children[i] | ||||
| 			unsafe { | ||||
| 				child.children[i + degree] = sibling.children[i] | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	for i := idx + 1; i < n.len; i++ { | ||||
|  | @ -333,7 +356,9 @@ fn (mut n mapnode) merge(idx int) { | |||
| 		n.values[i - 1] = n.values[i] | ||||
| 	} | ||||
| 	for i := idx + 2; i <= n.len; i++ { | ||||
| 		n.children[i - 1] = n.children[i] | ||||
| 		unsafe { | ||||
| 			n.children[i - 1] = n.children[i] | ||||
| 		} | ||||
| 	} | ||||
| 	child.len += sibling.len + 1 | ||||
| 	n.len-- | ||||
|  | @ -355,7 +380,7 @@ pub fn (mut m SortedMap) delete(key string) { | |||
| 		if isnil(m.root.children) { | ||||
| 			return | ||||
| 		} else { | ||||
| 			m.root = &mapnode(m.root.children[0]) | ||||
| 			m.root = unsafe {&mapnode(m.root.children[0])} | ||||
| 		} | ||||
| 		// free(tmp)
 | ||||
| 	} | ||||
|  | @ -369,13 +394,13 @@ fn (n &mapnode) subkeys(mut keys []string, at int) int { | |||
| 		// Traverse children and insert
 | ||||
| 		// keys inbetween children
 | ||||
| 		for i in 0..n.len { | ||||
| 			child := &mapnode(n.children[i]) | ||||
| 			child := unsafe {&mapnode(n.children[i])} | ||||
| 			position += child.subkeys(mut keys, position) | ||||
| 			keys[position] = n.keys[i] | ||||
| 			position++ | ||||
| 		} | ||||
| 		// Insert the keys of the last child
 | ||||
| 		child := &mapnode(n.children[n.len]) | ||||
| 		child := unsafe {&mapnode(n.children[n.len])} | ||||
| 		position += child.subkeys(mut keys, position) | ||||
| 	} else { | ||||
| 		// If leaf, insert keys
 | ||||
|  |  | |||
|  | @ -147,6 +147,7 @@ pub fn (s string) cstr() byteptr { | |||
| */ | ||||
| 
 | ||||
| // cstring_to_vstring creates a copy of cstr and turns it into a v string
 | ||||
| [unsafe_fn] | ||||
| pub fn cstring_to_vstring(cstr byteptr) string { | ||||
| 	return tos_clone(cstr) | ||||
| } | ||||
|  | @ -1432,12 +1433,16 @@ pub fn (s string) filter(func fn(b byte) bool) string { | |||
| 	for i in 0 .. s.len { | ||||
| 		mut b := s[i] | ||||
| 		if func(b) { | ||||
| 			buf[new_len] = b | ||||
| 			unsafe { | ||||
| 				buf[new_len] = b | ||||
| 			} | ||||
| 			new_len++ | ||||
| 		} | ||||
| 	} | ||||
| 	buf[new_len] = 0 | ||||
| 	return string(buf, new_len) | ||||
| 	unsafe { | ||||
| 		buf[new_len] = 0 | ||||
| 		return string(buf, new_len) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Allows multi-line strings to be formatted in a way that removes white-space
 | ||||
|  |  | |||
|  | @ -10,76 +10,45 @@ pub fn utf8_char_len(b byte) int { | |||
| // Convert utf32 to utf8
 | ||||
| // utf32 == Codepoint
 | ||||
| pub fn utf32_to_str(code u32) string { | ||||
| 	icode := int(code) // Prevents doing casts everywhere
 | ||||
| 	mut buffer := malloc(5) | ||||
| 	if icode <= 127/* 0x7F */ { | ||||
| 		buffer[0] = byte(icode) | ||||
| 		return tos(buffer, 1) | ||||
| 	} | ||||
| 	if icode <= 2047/* 0x7FF */ { | ||||
| 		buffer[0] = 192/*0xC0*/ | byte(icode>>6)/* 110xxxxx */ | ||||
| 
 | ||||
| 		buffer[1] = 128/*0x80*/ | byte(icode & 63/*0x3F*/)/* 10xxxxxx */ | ||||
| 
 | ||||
| 		return tos(buffer, 2) | ||||
| 	} | ||||
| 	if icode <= 65535/* 0xFFFF */ { | ||||
| 		buffer[0] = 224/*0xE0*/ | byte(icode>>12)/* 1110xxxx */ | ||||
| 
 | ||||
| 		buffer[1] = 128/*0x80*/ | (byte(icode>>6) & 63/*0x3F*/)/* 10xxxxxx */ | ||||
| 
 | ||||
| 		buffer[2] = 128/*0x80*/ | byte(icode & 63/*0x3F*/)/* 10xxxxxx */ | ||||
| 
 | ||||
| 		return tos(buffer, 3) | ||||
| 	} | ||||
| 	if icode <= 1114111/* 0x10FFFF */ { | ||||
| 		buffer[0] = 240/*0xF0*/ | byte(icode>>18)/* 11110xxx */ | ||||
| 
 | ||||
| 		buffer[1] = 128/*0x80*/ | (byte(icode>>12) & 63/*0x3F*/)/* 10xxxxxx */ | ||||
| 
 | ||||
| 		buffer[2] = 128/*0x80*/ | (byte(icode>>6) & 63/*0x3F*/)/* 10xxxxxx */ | ||||
| 
 | ||||
| 		buffer[3] = 128/*0x80*/ | byte(icode & 63/*0x3F*/)/* 10xxxxxx */ | ||||
| 
 | ||||
| 		return tos(buffer, 4) | ||||
| 	} | ||||
| 	return '' | ||||
| 	return utf32_to_str_no_malloc(code, buffer) | ||||
| } | ||||
| 
 | ||||
| // TODO copypasta
 | ||||
| pub fn utf32_to_str_no_malloc(code u32, buf voidptr) string { | ||||
| 	icode := int(code) // Prevents doing casts everywhere
 | ||||
| 	mut buffer := byteptr(buf) | ||||
| 	if icode <= 127/* 0x7F */ { | ||||
| 		buffer[0] = byte(icode) | ||||
| 		return tos(buffer, 1) | ||||
| 	} | ||||
| 	if icode <= 2047/* 0x7FF */ { | ||||
| 		buffer[0] = 192/*0xC0*/ | byte(icode>>6)/* 110xxxxx */ | ||||
| 	unsafe { | ||||
| 		mut buffer := byteptr(buf) | ||||
| 		if icode <= 127/* 0x7F */ { | ||||
| 			buffer[0] = byte(icode) | ||||
| 			return tos(buffer, 1) | ||||
| 		} | ||||
| 		if icode <= 2047/* 0x7FF */ { | ||||
| 			buffer[0] = 192/*0xC0*/ | byte(icode>>6)/* 110xxxxx */ | ||||
| 
 | ||||
| 		buffer[1] = 128/*0x80*/ | byte(icode & 63/*0x3F*/)/* 10xxxxxx */ | ||||
| 			buffer[1] = 128/*0x80*/ | byte(icode & 63/*0x3F*/)/* 10xxxxxx */ | ||||
| 
 | ||||
| 		return tos(buffer, 2) | ||||
| 	} | ||||
| 	if icode <= 65535/* 0xFFFF */ { | ||||
| 		buffer[0] = 224/*0xE0*/ | byte(icode>>12)/* 1110xxxx */ | ||||
| 			return tos(buffer, 2) | ||||
| 		} | ||||
| 		if icode <= 65535/* 0xFFFF */ { | ||||
| 			buffer[0] = 224/*0xE0*/ | byte(icode>>12)/* 1110xxxx */ | ||||
| 
 | ||||
| 		buffer[1] = 128/*0x80*/ | (byte(icode>>6) & 63/*0x3F*/)/* 10xxxxxx */ | ||||
| 			buffer[1] = 128/*0x80*/ | (byte(icode>>6) & 63/*0x3F*/)/* 10xxxxxx */ | ||||
| 
 | ||||
| 		buffer[2] = 128/*0x80*/ | byte(icode & 63/*0x3F*/)/* 10xxxxxx */ | ||||
| 			buffer[2] = 128/*0x80*/ | byte(icode & 63/*0x3F*/)/* 10xxxxxx */ | ||||
| 
 | ||||
| 		return tos(buffer, 3) | ||||
| 	} | ||||
| 	if icode <= 1114111/* 0x10FFFF */ { | ||||
| 		buffer[0] = 240/*0xF0*/ | byte(icode>>18)/* 11110xxx */ | ||||
| 			return tos(buffer, 3) | ||||
| 		} | ||||
| 		if icode <= 1114111/* 0x10FFFF */ { | ||||
| 			buffer[0] = 240/*0xF0*/ | byte(icode>>18)/* 11110xxx */ | ||||
| 
 | ||||
| 		buffer[1] = 128/*0x80*/ | (byte(icode>>12) & 63/*0x3F*/)/* 10xxxxxx */ | ||||
| 			buffer[1] = 128/*0x80*/ | (byte(icode>>12) & 63/*0x3F*/)/* 10xxxxxx */ | ||||
| 
 | ||||
| 		buffer[2] = 128/*0x80*/ | (byte(icode>>6) & 63/*0x3F*/)/* 10xxxxxx */ | ||||
| 			buffer[2] = 128/*0x80*/ | (byte(icode>>6) & 63/*0x3F*/)/* 10xxxxxx */ | ||||
| 
 | ||||
| 		buffer[3] = 128/*0x80*/ | byte(icode & 63/*0x3F*/)/* 10xxxxxx */ | ||||
| 			buffer[3] = 128/*0x80*/ | byte(icode & 63/*0x3F*/)/* 10xxxxxx */ | ||||
| 
 | ||||
| 		return tos(buffer, 4) | ||||
| 			return tos(buffer, 4) | ||||
| 		} | ||||
| 	} | ||||
| 	return '' | ||||
| } | ||||
|  | @ -183,7 +152,7 @@ fn utf8_str_len(s string) int { | |||
| 	mut l := 0 | ||||
| 	for i := 0; i < s.len; i++ { | ||||
| 		l++ | ||||
| 		c := s.str[i] | ||||
| 		c := unsafe {s.str[i]} | ||||
| 		if (c & (1 << 7)) != 0 { | ||||
| 			for t := byte(1 << 6); (c & t) != 0; t >>= 1 { | ||||
| 				i++ | ||||
|  | @ -199,7 +168,7 @@ fn utf8_str_visible_length(s string) int { | |||
| 	mut ul := 1 | ||||
| 	for i := 0; i < s.len; i+=ul { | ||||
| 		ul = 1 | ||||
| 		c := s.str[i] | ||||
| 		c := unsafe {s.str[i]} | ||||
| 		if (c & (1 << 7)) != 0 { | ||||
| 			for t := byte(1 << 6); (c & t) != 0; t >>= 1 { | ||||
| 				ul++ | ||||
|  | @ -211,12 +180,12 @@ fn utf8_str_visible_length(s string) int { | |||
| 		l++ | ||||
| 		// recognize combining characters
 | ||||
| 		if c == 0xcc || c == 0xcd { | ||||
| 			r := (u16(c) << 8) | s.str[i+1] | ||||
| 			r := (u16(c) << 8) | unsafe {s.str[i+1]} | ||||
| 			if r >= 0xcc80 && r < 0xcdb0 { // diacritical marks
 | ||||
| 				l-- | ||||
| 			} | ||||
| 		} else if c == 0xe1 || c == 0xe2 || c == 0xef { | ||||
| 			r := (u32(c) << 16) | (u32(s.str[i+1]) << 8) | s.str[i+2] | ||||
| 			r := (u32(c) << 16) | unsafe {(u32(s.str[i+1]) << 8) | s.str[i+2]} | ||||
| 			if (r >= 0xe1aab0 && r < 0xe1ac80) // diacritical marks extended
 | ||||
| 			|| (r >= 0xe1b780 && r < 0xe1b880) // diacritical marks supplement
 | ||||
| 			|| (r >= 0xe28390 && r < 0xe28480) // diacritical marks for symbols
 | ||||
|  |  | |||
|  | @ -84,26 +84,28 @@ pub fn decode_in_buffer(data &string, buffer byteptr) int { | |||
| 		mut char_c := 0 | ||||
| 		mut char_d := 0 | ||||
| 		if i < input_length { | ||||
| 			char_a = index[d[i]] | ||||
| 			char_a = index[unsafe {d[i]}] | ||||
| 			i++ | ||||
| 		} | ||||
| 		if i < input_length { | ||||
| 			char_b = index[d[i]] | ||||
| 			char_b = index[unsafe {d[i]}] | ||||
| 			i++ | ||||
| 		} | ||||
| 		if i < input_length { | ||||
| 			char_c = index[d[i]] | ||||
| 			char_c = index[unsafe {d[i]}] | ||||
| 			i++ | ||||
| 		} | ||||
| 		if i < input_length { | ||||
| 			char_d = index[d[i]] | ||||
| 			char_d = index[unsafe {d[i]}] | ||||
| 			i++ | ||||
| 		} | ||||
| 
 | ||||
| 		decoded_bytes := (char_a << 18) | (char_b << 12) | (char_c << 6) | (char_d << 0) | ||||
| 		b[j]   = byte(decoded_bytes >> 16) | ||||
| 		b[j+1] = byte((decoded_bytes >> 8) & 0xff) | ||||
| 		b[j+2] = byte((decoded_bytes >> 0) & 0xff) | ||||
| 		unsafe { | ||||
| 			b[j]   = byte(decoded_bytes >> 16) | ||||
| 			b[j+1] = byte((decoded_bytes >> 8) & 0xff) | ||||
| 			b[j+2] = byte((decoded_bytes >> 0) & 0xff) | ||||
| 		} | ||||
| 		j += 3 | ||||
| 	} | ||||
| 	return output_length | ||||
|  | @ -139,30 +141,34 @@ pub fn encode_in_buffer(data &string, buffer byteptr) int { | |||
| 		mut octet_c := 0 | ||||
| 
 | ||||
| 		if i < input_length { | ||||
| 			octet_a = int(d[i]) | ||||
| 			octet_a = int(unsafe {d[i]}) | ||||
| 			i++ | ||||
| 		} | ||||
| 		if i < input_length { | ||||
| 			octet_b = int(d[i]) | ||||
| 			octet_b = int(unsafe {d[i]}) | ||||
| 			i++ | ||||
| 		} | ||||
| 		if i < input_length { | ||||
| 			octet_c = int(d[i]) | ||||
| 			octet_c = int(unsafe {d[i]}) | ||||
| 			i++ | ||||
| 		} | ||||
| 
 | ||||
| 		triple := ((octet_a << 0x10) + (octet_b << 0x08) + octet_c) | ||||
| 
 | ||||
| 		b[j]   = etable[ (triple >> 3 * 6) & 63 ]  // 63 is 0x3F
 | ||||
| 		b[j+1] = etable[ (triple >> 2 * 6) & 63 ] | ||||
| 		b[j+2] = etable[ (triple >> 1 * 6) & 63 ] | ||||
| 		b[j+3] = etable[ (triple >> 0 * 6) & 63 ] | ||||
| 		unsafe { | ||||
| 			b[j]   = etable[ (triple >> 3 * 6) & 63 ]  // 63 is 0x3F
 | ||||
| 			b[j+1] = etable[ (triple >> 2 * 6) & 63 ] | ||||
| 			b[j+2] = etable[ (triple >> 1 * 6) & 63 ] | ||||
| 			b[j+3] = etable[ (triple >> 0 * 6) & 63 ] | ||||
| 		} | ||||
| 		j += 4 | ||||
| 	} | ||||
| 
 | ||||
| 	padding_length := ending_table[input_length % 3] | ||||
| 	for i = 0; i < padding_length; i++ { | ||||
| 		b[output_length - 1 - i] = `=` | ||||
| 		unsafe { | ||||
| 			b[output_length - 1 - i] = `=` | ||||
| 		} | ||||
| 	} | ||||
| 	return output_length | ||||
| } | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ pub fn validate_str(str string) bool { | |||
| pub fn validate(data byteptr, len int) bool { | ||||
| 	mut state := Utf8State{} | ||||
| 	for i := 0; i < len; i++ { | ||||
| 		s := data[i] | ||||
| 		s := unsafe {data[i]} | ||||
| 		if s == 0 { | ||||
| 			break | ||||
| 		} | ||||
|  |  | |||
|  | @ -14,14 +14,16 @@ fn (mut ws Client) read_handshake(seckey string) { | |||
| 		if res == 0 || res == -1 { | ||||
| 			ws.log.fatal('read_handshake: Failed to read handshake.') | ||||
| 		} | ||||
| 		if buffer[bytes_read] == `\n` && | ||||
| 		if unsafe {buffer[bytes_read] == `\n` && | ||||
| 			buffer[bytes_read - 1] == `\r` && buffer[bytes_read - 2] == `\n` && | ||||
| 			buffer[bytes_read - 3] == `\r` { | ||||
| 			buffer[bytes_read - 3] == `\r`} { | ||||
| 			break | ||||
| 		} | ||||
| 		bytes_read += buffer_size | ||||
| 	} | ||||
| 	buffer[max_buffer - 1] = `\0` | ||||
| 	unsafe { | ||||
| 		buffer[max_buffer - 1] = `\0` | ||||
| 	} | ||||
| 	ws.handshake_handler(string(byteptr(buffer)), seckey) | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -5,16 +5,18 @@ import crypto.sha1 | |||
| import encoding.base64 | ||||
| 
 | ||||
| fn htonl64(payload_len u64) byteptr { | ||||
| 	mut ret := malloc(8) | ||||
| 	ret[0] = byte(((payload_len & (u64(0xff) << 56)) >> 56) & 0xff) | ||||
| 	ret[1] = byte(((payload_len & (u64(0xff) << 48)) >> 48) & 0xff) | ||||
| 	ret[2] = byte(((payload_len & (u64(0xff) << 40)) >> 40) & 0xff) | ||||
| 	ret[3] = byte(((payload_len & (u64(0xff) << 32)) >> 32) & 0xff) | ||||
| 	ret[4] = byte(((payload_len & (u64(0xff) << 24)) >> 24) & 0xff) | ||||
| 	ret[5] = byte(((payload_len & (u64(0xff) << 16)) >> 16) & 0xff) | ||||
| 	ret[6] = byte(((payload_len & (u64(0xff) << 8)) >> 8) & 0xff) | ||||
| 	ret[7] = byte(((payload_len & (u64(0xff) << 0)) >> 0) & 0xff) | ||||
| 	return ret | ||||
| 	unsafe { | ||||
| 		mut ret := malloc(8) | ||||
| 		ret[0] = byte(((payload_len & (u64(0xff) << 56)) >> 56) & 0xff) | ||||
| 		ret[1] = byte(((payload_len & (u64(0xff) << 48)) >> 48) & 0xff) | ||||
| 		ret[2] = byte(((payload_len & (u64(0xff) << 40)) >> 40) & 0xff) | ||||
| 		ret[3] = byte(((payload_len & (u64(0xff) << 32)) >> 32) & 0xff) | ||||
| 		ret[4] = byte(((payload_len & (u64(0xff) << 24)) >> 24) & 0xff) | ||||
| 		ret[5] = byte(((payload_len & (u64(0xff) << 16)) >> 16) & 0xff) | ||||
| 		ret[6] = byte(((payload_len & (u64(0xff) << 8)) >> 8) & 0xff) | ||||
| 		ret[7] = byte(((payload_len & (u64(0xff) << 0)) >> 0) & 0xff) | ||||
| 		return ret | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn create_masking_key() []byte { | ||||
|  |  | |||
|  | @ -355,19 +355,20 @@ pub fn (mut ws Client) read() int { | |||
| 			} | ||||
| 		} | ||||
| 		if bytes_read == u64(header_len_offset) { | ||||
| 			frame.fin = (data[0] & 0x80) == 0x80 | ||||
| 			frame.rsv1 = (data[0] & 0x40) == 0x40 | ||||
| 			frame.rsv2 = (data[0] & 0x20) == 0x20 | ||||
| 			frame.rsv3 = (data[0] & 0x10) == 0x10 | ||||
| 			frame.opcode = OPCode(int(data[0] & 0x7F)) | ||||
| 			frame.mask = (data[1] & 0x80) == 0x80 | ||||
| 			frame.payload_len = u64(data[1] & 0x7F) | ||||
| 			data0 := unsafe {data[0]} | ||||
| 			frame.fin = (data0 & 0x80) == 0x80 | ||||
| 			frame.rsv1 = (data0 & 0x40) == 0x40 | ||||
| 			frame.rsv2 = (data0 & 0x20) == 0x20 | ||||
| 			frame.rsv3 = (data0 & 0x10) == 0x10 | ||||
| 			frame.opcode = OPCode(int(data0 & 0x7F)) | ||||
| 			frame.mask = (unsafe {data[1]} & 0x80) == 0x80 | ||||
| 			frame.payload_len = u64(unsafe {data[1]} & 0x7F) | ||||
| 			// masking key
 | ||||
| 			if frame.mask { | ||||
| 				frame.masking_key[0] = data[2] | ||||
| 				frame.masking_key[1] = data[3] | ||||
| 				frame.masking_key[2] = data[4] | ||||
| 				frame.masking_key[3] = data[5] | ||||
| 				frame.masking_key[0] = unsafe {data[2]} | ||||
| 				frame.masking_key[1] = unsafe {data[3]} | ||||
| 				frame.masking_key[2] = unsafe {data[4]} | ||||
| 				frame.masking_key[3] = unsafe {data[5]} | ||||
| 			} | ||||
| 			payload_len = frame.payload_len | ||||
| 			frame_size = u64(header_len) + payload_len | ||||
|  | @ -375,14 +376,14 @@ pub fn (mut ws Client) read() int { | |||
| 		if frame.payload_len == u64(126) && bytes_read == u64(extended_payload16_end_byte) { | ||||
| 			header_len += 2 | ||||
| 			mut extended_payload_len := 0 | ||||
| 			extended_payload_len |= data[2] << 8 | ||||
| 			extended_payload_len |= data[3] << 0 | ||||
| 			extended_payload_len |= unsafe {data[2]} << 8 | ||||
| 			extended_payload_len |= unsafe {data[3]} << 0 | ||||
| 			// masking key
 | ||||
| 			if frame.mask { | ||||
| 				frame.masking_key[0] = data[4] | ||||
| 				frame.masking_key[1] = data[5] | ||||
| 				frame.masking_key[2] = data[6] | ||||
| 				frame.masking_key[3] = data[7] | ||||
| 				frame.masking_key[0] = unsafe {data[4]} | ||||
| 				frame.masking_key[1] = unsafe {data[5]} | ||||
| 				frame.masking_key[2] = unsafe {data[6]} | ||||
| 				frame.masking_key[3] = unsafe {data[7]} | ||||
| 			} | ||||
| 			payload_len = u64(extended_payload_len) | ||||
| 			frame_size = u64(header_len) + payload_len | ||||
|  | @ -393,20 +394,20 @@ pub fn (mut ws Client) read() int { | |||
| 		} else if frame.payload_len == u64(127) && bytes_read == u64(extended_payload64_end_byte) { | ||||
| 			header_len += 8 // TODO Not sure...
 | ||||
| 			mut extended_payload_len := u64(0) | ||||
| 			extended_payload_len |= u64(data[2]) << 56 | ||||
| 			extended_payload_len |= u64(data[3]) << 48 | ||||
| 			extended_payload_len |= u64(data[4]) << 40 | ||||
| 			extended_payload_len |= u64(data[5]) << 32 | ||||
| 			extended_payload_len |= u64(data[6]) << 24 | ||||
| 			extended_payload_len |= u64(data[7]) << 16 | ||||
| 			extended_payload_len |= u64(data[8]) << 8 | ||||
| 			extended_payload_len |= u64(data[9]) << 0 | ||||
| 			extended_payload_len |= u64(unsafe {data[2]}) << 56 | ||||
| 			extended_payload_len |= u64(unsafe {data[3]}) << 48 | ||||
| 			extended_payload_len |= u64(unsafe {data[4]}) << 40 | ||||
| 			extended_payload_len |= u64(unsafe {data[5]}) << 32 | ||||
| 			extended_payload_len |= u64(unsafe {data[6]}) << 24 | ||||
| 			extended_payload_len |= u64(unsafe {data[7]}) << 16 | ||||
| 			extended_payload_len |= u64(unsafe {data[8]}) << 8 | ||||
| 			extended_payload_len |= u64(unsafe {data[9]}) << 0 | ||||
| 			// masking key
 | ||||
| 			if frame.mask { | ||||
| 				frame.masking_key[0] = data[10] | ||||
| 				frame.masking_key[1] = data[11] | ||||
| 				frame.masking_key[2] = data[12] | ||||
| 				frame.masking_key[3] = data[13] | ||||
| 				frame.masking_key[0] = unsafe {data[10]} | ||||
| 				frame.masking_key[1] = unsafe {data[11]} | ||||
| 				frame.masking_key[2] = unsafe {data[12]} | ||||
| 				frame.masking_key[3] = unsafe {data[13]} | ||||
| 			} | ||||
| 			payload_len = extended_payload_len | ||||
| 			frame_size = u64(header_len) + payload_len | ||||
|  | @ -419,7 +420,9 @@ pub fn (mut ws Client) read() int { | |||
| 	// unmask the payload
 | ||||
| 	if frame.mask { | ||||
| 		for i in 0 .. payload_len { | ||||
| 			data[header_len + i] ^= frame.masking_key[i % 4] & 0xff | ||||
| 			unsafe { | ||||
| 				data[header_len + i] ^= frame.masking_key[i % 4] & 0xff | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	if ws.fragments.len > 0 && frame.opcode in [.text_frame, .binary_frame] { | ||||
|  | @ -474,11 +477,13 @@ pub fn (mut ws Client) read() int { | |||
| 				} | ||||
| 				ws.fragments = [] | ||||
| 			} | ||||
| 			payload[payload_len] = `\0` | ||||
| 			unsafe { | ||||
| 				payload[payload_len] = `\0` | ||||
| 			} | ||||
| 			if frame.opcode == .text_frame && payload_len > 0 { | ||||
| 				if !utf8.validate(payload, int(payload_len)) { | ||||
| 					ws.log.error('malformed utf8 payload') | ||||
| 					ws.send_error_event('Recieved malformed utf8.') | ||||
| 					ws.send_error_event('Received malformed utf8.') | ||||
| 					ws.close(1007, 'malformed utf8 payload') | ||||
| 					goto free_data | ||||
| 					return -1 | ||||
|  | @ -556,10 +561,10 @@ pub fn (mut ws Client) read() int { | |||
| 		mut code := 0 | ||||
| 		mut reason := '' | ||||
| 		if payload_len > 2 { | ||||
| 			code = (int(data[header_len]) << 8) + int(data[header_len + 1]) | ||||
| 			code = (int(unsafe {data[header_len]}) << 8) + int(unsafe {data[header_len + 1]}) | ||||
| 			header_len += 2 | ||||
| 			payload_len -= 2 | ||||
| 			reason = string(&data[header_len]) | ||||
| 			reason = unsafe {string(&data[header_len])} | ||||
| 			ws.log.info('Closing with reason: $reason & code: $code') | ||||
| 			if reason.len > 1 && !utf8.validate(reason.str, reason.len) { | ||||
| 				ws.log.error('malformed utf8 payload') | ||||
|  |  | |||
|  | @ -76,8 +76,8 @@ pub fn environ() map[string]string { | |||
| 		C.FreeEnvironmentStringsW(estrings) | ||||
| 	} $else { | ||||
| 		e := &charptr(C.environ) | ||||
| 		for i := 0; !isnil(e[i]); i++ { | ||||
| 			eline := cstring_to_vstring(byteptr(e[i])) | ||||
| 		for i := 0; !isnil(unsafe {e[i]}); i++ { | ||||
| 			eline := unsafe {cstring_to_vstring(byteptr(e[i]))} | ||||
| 			eq_index := eline.index_byte(`=`) | ||||
| 			if eq_index > 0 { | ||||
| 				res[eline[0..eq_index]] = eline[eq_index + 1..] | ||||
|  |  | |||
							
								
								
									
										11
									
								
								vlib/os/os.v
								
								
								
								
							
							
						
						
									
										11
									
								
								vlib/os/os.v
								
								
								
								
							|  | @ -120,11 +120,12 @@ pub fn read_file(path string) ?string { | |||
| 	fsize := C.ftell(fp) | ||||
| 	// C.fseek(fp, 0, SEEK_SET)  // same as `C.rewind(fp)` below
 | ||||
| 	C.rewind(fp) | ||||
| 	mut str := &byte(0) | ||||
| 	unsafe { str = malloc(fsize + 1) } | ||||
| 	C.fread(str, fsize, 1, fp) | ||||
| 	str[fsize] = 0 | ||||
| 	return string(str,fsize) | ||||
| 	unsafe { | ||||
| 		mut str := malloc(fsize + 1) | ||||
| 		C.fread(str, fsize, 1, fp) | ||||
| 		str[fsize] = 0 | ||||
| 		return string(str,fsize) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /***************************** Utility  ops ************************/ | ||||
|  |  | |||
|  | @ -52,7 +52,7 @@ fn init_os_args(argc int, argv &&byte) []string { | |||
| 	// mut args := []string{len:argc}
 | ||||
| 	for i in 0 .. argc { | ||||
| 		// args [i] = string(argv[i])
 | ||||
| 		args << string(argv[i]) | ||||
| 		args << unsafe {string(argv[i])} | ||||
| 	} | ||||
| 	return args | ||||
| } | ||||
|  |  | |||
|  | @ -80,7 +80,7 @@ mut: | |||
| fn init_os_args_wide(argc int, argv &byteptr) []string { | ||||
| 	mut args := []string{} | ||||
| 	for i in 0..argc { | ||||
| 		args << string_from_wide(&u16(argv[i])) | ||||
| 		args << string_from_wide(unsafe {&u16(argv[i])}) | ||||
| 	} | ||||
| 	return args | ||||
| } | ||||
|  |  | |||
|  | @ -136,7 +136,9 @@ const ( | |||
| pub fn string(len int) string { | ||||
| 	mut buf := malloc(len) | ||||
| 	for i in 0..len { | ||||
| 		buf[i] = chars[intn(chars.len)] | ||||
| 		unsafe { | ||||
| 			buf[i] = chars[intn(chars.len)] | ||||
| 		} | ||||
| 	} | ||||
| 	return string(buf, len) | ||||
| } | ||||
|  |  | |||
|  | @ -90,18 +90,19 @@ fn utf8util_char_len(b byte) int { | |||
| // get_char get a char from position i and return an u32 with the unicode code
 | ||||
| [inline] | ||||
| fn (re RE) get_char(in_txt string, i int) (u32,int) { | ||||
| 	ini := unsafe {in_txt.str[i]} | ||||
| 	// ascii 8 bit
 | ||||
| 	if (re.flag & f_bin) !=0 || | ||||
| 		in_txt.str[i] & 0x80 == 0 | ||||
| 		ini & 0x80 == 0 | ||||
| 	{ | ||||
| 		return u32(in_txt.str[i]), 1 | ||||
| 		return u32(ini), 1 | ||||
| 	} | ||||
| 	// unicode char
 | ||||
| 	char_len := utf8util_char_len(in_txt.str[i]) | ||||
| 	char_len := utf8util_char_len(ini) | ||||
| 	mut tmp := 0 | ||||
| 	mut ch := u32(0) | ||||
| 	for tmp < char_len { | ||||
| 		ch = (ch << 8) | in_txt.str[i+tmp] | ||||
| 		ch = (ch << 8) | unsafe {in_txt.str[i+tmp]} | ||||
| 		tmp++ | ||||
| 	} | ||||
| 	return ch,char_len | ||||
|  | @ -112,16 +113,16 @@ fn (re RE) get_char(in_txt string, i int) (u32,int) { | |||
| fn (re RE) get_charb(in_txt byteptr, i int) (u32,int) { | ||||
| 	// ascii 8 bit
 | ||||
| 	if (re.flag & f_bin) !=0 || | ||||
| 		in_txt[i] & 0x80 == 0 | ||||
| 		unsafe {in_txt[i]} & 0x80 == 0 | ||||
| 	{ | ||||
| 		return u32(in_txt[i]), 1 | ||||
| 		return u32(unsafe {in_txt[i]}), 1 | ||||
| 	} | ||||
| 	// unicode char
 | ||||
| 	char_len := utf8util_char_len(in_txt[i]) | ||||
| 	char_len := utf8util_char_len(unsafe {in_txt[i]}) | ||||
| 	mut tmp := 0 | ||||
| 	mut ch := u32(0) | ||||
| 	for tmp < char_len { | ||||
| 		ch = (ch << 8) | in_txt[i+tmp] | ||||
| 		ch = (ch << 8) | unsafe {in_txt[i+tmp]} | ||||
| 		tmp++ | ||||
| 	} | ||||
| 	return ch,char_len | ||||
|  | @ -488,15 +489,19 @@ fn (re RE) get_char_class(pc int) string { | |||
| 	for cc_i >= 0 && cc_i < re.cc.len && re.cc[cc_i].cc_type != cc_end { | ||||
| 
 | ||||
| 		if re.cc[cc_i].cc_type == cc_bsls { | ||||
| 			buf_ptr[i++] = `\\` | ||||
| 			buf_ptr[i++] = byte(re.cc[cc_i].ch0) | ||||
| 			unsafe { | ||||
| 				buf_ptr[i++] = `\\` | ||||
| 				buf_ptr[i++] = byte(re.cc[cc_i].ch0) | ||||
| 			} | ||||
| 		} | ||||
| 		else if re.cc[cc_i].ch0 == re.cc[cc_i].ch1 { | ||||
| 			tmp = 3 | ||||
| 			for tmp >= 0 { | ||||
| 				x := byte((re.cc[cc_i].ch0 >> (tmp*8)) & 0xFF) | ||||
| 				if x != 0 { | ||||
| 					buf_ptr[i++] = x | ||||
| 					unsafe { | ||||
| 						buf_ptr[i++] = x | ||||
| 					} | ||||
| 				} | ||||
| 				tmp-- | ||||
| 			} | ||||
|  | @ -506,23 +511,31 @@ fn (re RE) get_char_class(pc int) string { | |||
| 			for tmp >= 0 { | ||||
| 				x := byte((re.cc[cc_i].ch0 >> (tmp*8)) & 0xFF) | ||||
| 				if x != 0 { | ||||
| 					buf_ptr[i++] = x | ||||
| 					unsafe { | ||||
| 						buf_ptr[i++] = x | ||||
| 					} | ||||
| 				} | ||||
| 				tmp-- | ||||
| 			} | ||||
| 			buf_ptr[i++] = `-` | ||||
| 			unsafe { | ||||
| 				buf_ptr[i++] = `-` | ||||
| 			} | ||||
| 			tmp = 3 | ||||
| 			for tmp >= 0 { | ||||
| 				x := byte((re.cc[cc_i].ch1 >> (tmp*8)) & 0xFF) | ||||
| 				if x != 0 { | ||||
| 					buf_ptr[i++] = x | ||||
| 					unsafe { | ||||
| 						buf_ptr[i++] = x | ||||
| 					} | ||||
| 				} | ||||
| 				tmp-- | ||||
| 			} | ||||
| 		} | ||||
| 		cc_i++ | ||||
| 	} | ||||
| 	buf_ptr[i] = byte(0) | ||||
| 	unsafe { | ||||
| 		buf_ptr[i] = byte(0) | ||||
| 	} | ||||
| 
 | ||||
| 	return tos_clone( buf_ptr ) | ||||
| } | ||||
|  | @ -689,7 +702,9 @@ fn (re RE) parse_quantifier(in_txt string, in_i int) (int, int, int, bool) { | |||
| 	mut ch := byte(0) | ||||
| 
 | ||||
| 	for i < in_txt.len { | ||||
| 		ch = in_txt.str[i] | ||||
| 		unsafe { | ||||
| 			ch = in_txt.str[i] | ||||
| 		} | ||||
| 
 | ||||
| 		//println("${ch:c} status: $status")
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -2993,6 +2993,20 @@ pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) table.Type { | |||
| 		typ_sym.name.ends_with('ptr')) && !typ.has_flag(.variadic) { // byteptr, charptr etc
 | ||||
| 		c.error('type `$typ_sym.name` does not support indexing', node.pos) | ||||
| 	} | ||||
| 	if !c.inside_unsafe && (typ.is_ptr() || typ.is_pointer()) { | ||||
| 		mut is_ok := false | ||||
| 		if node.left is ast.Ident { | ||||
| 			ident := node.left as ast.Ident | ||||
| 			scope := c.file.scope.innermost(ident.pos.pos) | ||||
| 			if v := scope.find_var(ident.name) { | ||||
| 				// `mut param []T` function parameter
 | ||||
| 				is_ok = v.is_mut && v.is_arg && !typ.deref().is_ptr() | ||||
| 			} | ||||
| 		} | ||||
| 		if !is_ok { | ||||
| 			c.warn('pointer indexing is only allowed in `unsafe` blocks', node.pos) | ||||
| 		} | ||||
| 	} | ||||
| 	if node.index !is ast.RangeExpr { // [1]
 | ||||
| 		index_type := c.expr(node.index) | ||||
| 		c.check_index_type(typ_sym, index_type, node.pos) | ||||
|  |  | |||
|  | @ -1,34 +1,48 @@ | |||
| vlib/v/checker/tests/unsafe_required.v:4:6: error: pointer arithmetic is only allowed in `unsafe` blocks | ||||
| vlib/v/checker/tests/unsafe_required.v:4:6: error: pointer arithmetic is only allowed in `unsafe` blocks  | ||||
|     2 |     v := 5 | ||||
|     3 |     mut p := &v | ||||
|     4 |     p++ | ||||
|       |      ~~ | ||||
|     5 |     p += 2 | ||||
|     6 |     _ := v | ||||
| vlib/v/checker/tests/unsafe_required.v:5:7: error: pointer arithmetic is only allowed in `unsafe` blocks | ||||
| vlib/v/checker/tests/unsafe_required.v:5:7: error: pointer arithmetic is only allowed in `unsafe` blocks  | ||||
|     3 |     mut p := &v | ||||
|     4 |     p++ | ||||
|     5 |     p += 2 | ||||
|       |       ~~ | ||||
|     6 |     _ := v | ||||
|     7 | } | ||||
| vlib/v/checker/tests/unsafe_required.v:11:14: error: pointer arithmetic is only allowed in `unsafe` blocks | ||||
| vlib/v/checker/tests/unsafe_required.v:11:14: error: pointer arithmetic is only allowed in `unsafe` blocks  | ||||
|     9 | fn test_ptr_infix() { | ||||
|    10 |     v := 4 | ||||
|    11 |     mut q := &v - 1 | ||||
|       |              ^ | ||||
|    12 |     q = q + 3 | ||||
|    13 |     _ := q | ||||
| vlib/v/checker/tests/unsafe_required.v:12:9: error: pointer arithmetic is only allowed in `unsafe` blocks | ||||
| vlib/v/checker/tests/unsafe_required.v:12:9: error: pointer arithmetic is only allowed in `unsafe` blocks  | ||||
|    10 |     v := 4 | ||||
|    11 |     mut q := &v - 1 | ||||
|    12 |     q = q + 3 | ||||
|       |         ^ | ||||
|    13 |     _ := q | ||||
|    14 |     _ := v | ||||
| vlib/v/checker/tests/unsafe_required.v:24:7: error: method `S1.f` must be called from an `unsafe` block | ||||
| vlib/v/checker/tests/unsafe_required.v:24:7: error: method `S1.f` must be called from an `unsafe` block  | ||||
|    22 | fn test_funcs() { | ||||
|    23 |     s := S1{} | ||||
|    24 |     s.f() | ||||
|       |       ~~~ | ||||
|    25 | } | ||||
|    26 | | ||||
| vlib/v/checker/tests/unsafe_required.v:32:7: error: pointer indexing is only allowed in `unsafe` blocks  | ||||
|    30 |     _ = b[0] | ||||
|    31 |     c := &b | ||||
|    32 |     _ = c[0] | ||||
|       |          ~~~ | ||||
|    33 |      | ||||
|    34 |     v := 4 | ||||
| vlib/v/checker/tests/unsafe_required.v:36:10: error: pointer indexing is only allowed in `unsafe` blocks  | ||||
|    34 |     v := 4 | ||||
|    35 |     p := &v | ||||
|    36 |     _ = p[0] | ||||
|       |          ~~~ | ||||
|    37 | } | ||||
|  |  | |||
|  | @ -23,3 +23,15 @@ fn test_funcs() { | |||
|     s := S1{} | ||||
|     s.f() | ||||
| } | ||||
| 
 | ||||
| fn test_ptr_index(mut a []string) { | ||||
| 	_ = a[0] | ||||
| 	b := ['jo'] | ||||
| 	_ = b[0] | ||||
| 	c := &b | ||||
| 	_ = c[0] | ||||
|      | ||||
|     v := 4 | ||||
|     p := &v | ||||
|     _ = p[0] | ||||
| } | ||||
|  |  | |||
|  | @ -212,11 +212,13 @@ pub fn read_file(file_path string) ?string { | |||
| 	} | ||||
| 	// BOM check
 | ||||
| 	if raw_text.len >= 3 { | ||||
| 		c_text := raw_text.str | ||||
| 		if c_text[0] == 0xEF && c_text[1] == 0xBB && c_text[2] == 0xBF { | ||||
| 			// skip three BOM bytes
 | ||||
| 			offset_from_begin := 3 | ||||
| 			raw_text = tos(c_text[offset_from_begin], vstrlen(c_text) - offset_from_begin) | ||||
| 		unsafe { | ||||
| 			c_text := raw_text.str | ||||
| 			if c_text[0] == 0xEF && c_text[1] == 0xBB && c_text[2] == 0xBF { | ||||
| 				// skip three BOM bytes
 | ||||
| 				offset_from_begin := 3 | ||||
| 				raw_text = tos(c_text[offset_from_begin], vstrlen(c_text) - offset_from_begin) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return raw_text | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue