Mercurial > hg
comparison mercurial/cext/manifest.c @ 35810:113a30b87716 stable
lazymanifest: avoid reading uninitialized memory
I got errors running tests with clang UBSAN [1] enabled. One of them is:
```
--- test-dirstate.t
+++ test-dirstate.t.err
@@ -85,9 +85,115 @@
$ echo "[extensions]" >> .hg/hgrc
$ echo "dirstateex=../dirstateexception.py" >> .hg/hgrc
$ hg up 0
- abort: simulated error while recording dirstateupdates
- [255]
+ mercurial/cext/manifest.c:781:13: runtime error: load of value 190, which is not a valid value for type 'bool'
+ #0 0x7f668a8cf748 in lazymanifest_diff mercurial/cext/manifest.c:781
+ #1 0x7f6692fc1dc4 in call_function Python-2.7.11/Python/ceval.c:4350
+ .......
+ SUMMARY: UndefinedBehaviorSanitizer: invalid-bool-load mercurial/cext/manifest.c:781:13 in
+ [1]
$ hg log -r . -T '{rev}\n'
1
$ hg status
- ? a
```
While the code is not technically wrong, but switching the condition would
make clang UBSAN happy. So let's do it.
The uninitialized memory could come from, for example, `lazymanifest_copy`
allocates `self->maxlines` items but only writes the first `self->lines`
items.
[1]: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
Test Plan:
Run `test-dirstate.t` with UBSAN and it no longer reports the issue.
Differential Revision: https://phab.mercurial-scm.org/D1948
author | Jun Wu <quark@fb.com> |
---|---|
date | Tue, 30 Jan 2018 20:32:48 -0800 |
parents | 6ece4a85c350 |
children | 1f8c3fadbb8e |
comparison
equal
deleted
inserted
replaced
35809:f9a82b9b2c36 | 35810:113a30b87716 |
---|---|
776 int result; | 776 int result; |
777 PyObject *key; | 777 PyObject *key; |
778 PyObject *outer; | 778 PyObject *outer; |
779 /* If we're looking at a deleted entry and it's not | 779 /* If we're looking at a deleted entry and it's not |
780 * the end of the manifest, just skip it. */ | 780 * the end of the manifest, just skip it. */ |
781 if (left->deleted && sneedle < self->numlines) { | 781 if (sneedle < self->numlines && left->deleted) { |
782 sneedle++; | 782 sneedle++; |
783 continue; | 783 continue; |
784 } | 784 } |
785 if (right->deleted && oneedle < other->numlines) { | 785 if (oneedle < other->numlines && right->deleted) { |
786 oneedle++; | 786 oneedle++; |
787 continue; | 787 continue; |
788 } | 788 } |
789 /* if we're at the end of either manifest, then we | 789 /* if we're at the end of either manifest, then we |
790 * know the remaining items are adds so we can skip | 790 * know the remaining items are adds so we can skip |