Mercurial > hg
view mercurial/peer.py @ 24286:40528ad1b1e8
lazymanifest: don't depend on printf's 'hh' format to work
Where we convert a 20-byte binary to a 40-byte hex string in
lazymanifest_setitem(), we use sprintf("%02hhx", hash[i]). As Matt
Harbison found out, 'hh' seems to be ignored on some platforms (Visual
Studio?). If char is signed on such platforms, the value gets
sign-extended as it gets promoted into an int when passed into the
variadic sprintf(). The resulting integer value will then be printed
with leading f's (14 of them on 64-bit systems), since the '2' in the
format string indicates only minimum number of characters. This is
both incorrect and runs the risk of writing outside of allocated
memory (as Matt reported).
To fix, let's cast the value to unsigned char before passing it to
sprintf(). Also drop the poorly supported 'hh' formatting that now
becomes unnecessary.
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Thu, 12 Mar 2015 09:06:45 -0700 |
parents | 4ed6b3a24661 |
children | cbbdd085c991 |
line wrap: on
line source
# peer.py - repository base classes for mercurial # # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com> # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. from i18n import _ import error class peerrepository(object): def capable(self, name): '''tell whether repo supports named capability. return False if not supported. if boolean capability, return True. if string capability, return string.''' caps = self._capabilities() if name in caps: return True name_eq = name + '=' for cap in caps: if cap.startswith(name_eq): return cap[len(name_eq):] return False def requirecap(self, name, purpose): '''raise an exception if the given capability is not present''' if not self.capable(name): raise error.CapabilityError( _('cannot %s; remote repository does not ' 'support the %r capability') % (purpose, name)) def local(self): '''return peer as a localrepo, or None''' return None def peer(self): return self def canpush(self): return True def close(self): pass