mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	kbtree: pointer UB and unitialized value fixes
- don't underflow itr->p pointer (C standard only allows one past the end, not one before the beginning) - make sure itr->p->i is always initialized (even when not used) - don't rely on `NULL < &object` (likely UB)
This commit is contained in:
		| @@ -317,7 +317,7 @@ | |||||||
| #define __KB_ITR(name, key_t, kbnode_t) \ | #define __KB_ITR(name, key_t, kbnode_t) \ | ||||||
| 	static inline void kb_itr_first_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \ | 	static inline void kb_itr_first_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \ | ||||||
| 	{ \ | 	{ \ | ||||||
| 		itr->p = 0; \ | 		itr->p = NULL; \ | ||||||
| 		if (b->n_keys == 0) return; \ | 		if (b->n_keys == 0) return; \ | ||||||
| 		itr->p = itr->stack; \ | 		itr->p = itr->stack; \ | ||||||
| 		itr->p->x = b->root; itr->p->i = 0; \ | 		itr->p->x = b->root; itr->p->i = 0; \ | ||||||
| @@ -329,7 +329,7 @@ | |||||||
| 	} \ | 	} \ | ||||||
| 	static inline int kb_itr_next_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \ | 	static inline int kb_itr_next_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \ | ||||||
| 	{ \ | 	{ \ | ||||||
| 		if (itr->p < itr->stack) return 0; \ | 		if (itr->p == NULL) return 0; \ | ||||||
| 		for (;;) { \ | 		for (;;) { \ | ||||||
| 			++itr->p->i; \ | 			++itr->p->i; \ | ||||||
| 			while (itr->p->x && itr->p->i <= itr->p->x->n) { \ | 			while (itr->p->x && itr->p->i <= itr->p->x->n) { \ | ||||||
| @@ -337,22 +337,28 @@ | |||||||
| 				itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[itr->p->i] : 0; \ | 				itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[itr->p->i] : 0; \ | ||||||
| 				++itr->p; \ | 				++itr->p; \ | ||||||
| 			} \ | 			} \ | ||||||
|  | 			if (itr->p == itr->stack) { \ | ||||||
|  | 				itr->p = NULL; \ | ||||||
|  | 				return 0; \ | ||||||
|  | 			} \ | ||||||
| 			--itr->p; \ | 			--itr->p; \ | ||||||
| 			if (itr->p < itr->stack) return 0; \ |  | ||||||
| 			if (itr->p->x && itr->p->i < itr->p->x->n) return 1; \ | 			if (itr->p->x && itr->p->i < itr->p->x->n) return 1; \ | ||||||
| 		} \ | 		} \ | ||||||
| 	} \ | 	} \ | ||||||
| 	static inline int kb_itr_prev_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \ | 	static inline int kb_itr_prev_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \ | ||||||
| 	{ \ | 	{ \ | ||||||
| 		if (itr->p < itr->stack) return 0; \ | 		if (itr->p == NULL) return 0; \ | ||||||
| 		for (;;) { \ | 		for (;;) { \ | ||||||
| 			while (itr->p->x && itr->p->i >= 0) { \ | 			while (itr->p->x && itr->p->i >= 0) { \ | ||||||
| 				itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[itr->p->i] : 0; \ | 				itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[itr->p->i] : 0; \ | ||||||
| 				itr->p[1].i = itr->p[1].x ? itr->p[1].x->n : -1; \ | 				itr->p[1].i = itr->p[1].x ? itr->p[1].x->n : -1; \ | ||||||
| 				++itr->p; \ | 				++itr->p; \ | ||||||
| 			} \ | 			} \ | ||||||
|  | 			if (itr->p == itr->stack) { \ | ||||||
|  | 				itr->p = NULL; \ | ||||||
|  | 				return 0; \ | ||||||
|  | 			} \ | ||||||
| 			--itr->p; \ | 			--itr->p; \ | ||||||
| 			if (itr->p < itr->stack) return 0; \ |  | ||||||
| 			--itr->p->i; \ | 			--itr->p->i; \ | ||||||
| 			if (itr->p->x && itr->p->i >= 0) return 1; \ | 			if (itr->p->x && itr->p->i >= 0) return 1; \ | ||||||
| 		} \ | 		} \ | ||||||
| @@ -374,6 +380,7 @@ | |||||||
| 			itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[i + 1] : 0; \ | 			itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[i + 1] : 0; \ | ||||||
| 			++itr->p; \ | 			++itr->p; \ | ||||||
| 		} \ | 		} \ | ||||||
|  | 		itr->p->i = 0; \ | ||||||
| 		return 0; \ | 		return 0; \ | ||||||
| 	} \ | 	} \ | ||||||
| 	static inline int kb_itr_get_##name(kbtree_##name##_t *b, key_t k, kbitr_##name##_t *itr) \ | 	static inline int kb_itr_get_##name(kbtree_##name##_t *b, key_t k, kbitr_##name##_t *itr) \ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Björn Linse
					Björn Linse