# # # patch "transforms.hh" # from [7b1ad2508a1fed5c39b318d8d1dc1fb1b5f2725b] # to [17ac404112076cf58410b6356b79640fa2e5923e] # # patch "vocab.cc" # from [90093cefdae518acc7e3381931a89fab27c1cdaf] # to [aa925026f92ed878a7c4bc8f5f418f6cae3d29f8] # # patch "vocab.hh" # from [c6a7cc514b64b15428fb5548a4deda1fc1a212b7] # to [3a8c252a8f3f180aed8b200ee4a9c880ba51d915] # # patch "vocab_hash.hh" # from [1bf71979cd58adf60349d0fb28459176c92f287b] # to [4ec39d236ead9a0833db8bb8ad611a6188fbecb3] # # patch "vocab_macros.hh" # from [7025028f87c647715e14fb50c13866e8df52d684] # to [27299229caa60ce0b18122ad5e03e17eb0f1f14f] # # patch "vocab_terms.hh" # from [80283d95bc08f3a9f8c1c503ebeebb51b03c384e] # to [c35150005f1e928769604620caa4e894416a3265] # ============================================================ --- transforms.hh 7b1ad2508a1fed5c39b318d8d1dc1fb1b5f2725b +++ transforms.hh 17ac404112076cf58410b6356b79640fa2e5923e @@ -48,7 +48,7 @@ base64 encode_base64(T const & in) template base64 encode_base64(T const & in) -{ return base64(T(xform(in()))); } +{ return base64(xform(in())); } template T decode_base64(base64 const & in) @@ -64,7 +64,7 @@ void encode_hexenc(T const & in, hexenc< template void encode_hexenc(T const & in, hexenc & out) -{ out = hexenc(T(xform(in()))); } +{ out = hexenc(xform(in())); } template void decode_hexenc(hexenc const & in, T & out) ============================================================ --- vocab.cc 90093cefdae518acc7e3381931a89fab27c1cdaf +++ vocab.cc aa925026f92ed878a7c4bc8f5f418f6cae3d29f8 @@ -19,45 +19,26 @@ using std::string; // verifiers for various types of data -// the verify() stuff gets a little complicated; there doesn't seem to be a -// really nice way to achieve what we want with c++'s type system. the -// problem is this: we want to give verify(file_path) and verify(local_path) -// access to the internals of file_path and local_path, i.e. make them -// friends, so they can normalize the file paths they're given. this means -// that verify() needs to be declared publically, so that the definition of -// these classes can refer to them. it also means that they -- and all other -// ATOMIC types -- cannot fall back on a templated version of verify if no -// other version is defined, because, well, the friend thing and the template -// thing just don't work out, as far as I can tell. So, every ATOMIC type -// needs an explicitly defined verify() function, so we have both ATOMIC() and -// ATOMIC_NOVERIFY() macros, the latter of which defines a type-specific noop -// verify function. DECORATE and ENCODING, on the other hand, cannot make use -// of a trick like these, because they are template types themselves, and we -// want to be able to define verify(hexenc) without defining -// verify(hexenc) at the same time, for instance. Fortunately, these -// types never need to be friends with their verify functions (yet...), so we -// _can_ use a templated fallback function. This templated function is used -// _only_ by DECORATE and ENCODING; it would be nice to make it take an -// argument of type T1 to document that, but for some reason that doesn't -// work either. -template -static inline void -verify(T & val) -{} +// Every ENCODING and ATOMIC type not defined with the _NOVERIFY variant in +// vocab_terms.hh must have a verify function defined here. DECORATE types +// use the verify function of their inner type. -template -static inline void -verify_full(T & val) -{ val.ok = true; } +// ENCODING types ... hexenc has a fixed size, hexenc doesn't. +template +inline void +verify(hexenc const & val) +{ + for (string::const_iterator i = val().begin(); i != val().end(); ++i) + { + N(is_xdigit(*i), + F("bad character '%c' in id name '%s'") % *i % val); + } +} -// NOTE: _not_ verify_full; you use verify_full for ATOMICs, verify() for -// everything else. +template <> inline void -verify(hexenc & val) +verify(hexenc const & val) { - if (val.ok) - return; - if (val().empty()) return; @@ -68,43 +49,41 @@ verify(hexenc & val) N(is_xdigit(*i), F("bad character '%c' in id name '%s'") % *i % val); } - val.ok = true; } +// ATOMIC types ... inline void -verify_full(symbol & val) +verify(symbol const & val) { for (string::const_iterator i = val().begin(); i != val().end(); ++i) { N(is_alnum(*i) || *i == '_', F("bad character '%c' in symbol '%s'") % *i % val); } - - val.ok = true; } inline void -verify_full(cert_name & val) +verify(cert_name const & val) { string::size_type pos = val().find_first_not_of(constants::legal_cert_name_bytes); N(pos == string::npos, F("bad character '%c' in cert name '%s'") % val().at(pos) % val); - - val.ok = true; } inline void -verify_full(rsa_keypair_id & val) +verify(rsa_keypair_id const & val) { string::size_type pos = val().find_first_not_of(constants::legal_key_name_bytes); N(pos == string::npos, F("bad character '%c' in key name '%s'") % val().at(pos) % val); +} - val.ok = true; -} +// These two may modify their argument, to set a more sensible value when +// initializing from the empty string or the default constructor; therefore +// they cannot take a const argument and must be friends with their class. inline void -verify_full(netsync_session_key & val) +verify(netsync_session_key & val) { if (val().size() == 0) { @@ -114,12 +93,10 @@ verify_full(netsync_session_key & val) N(val().size() == constants::netsync_session_key_length_in_bytes, F("Invalid key length of %d bytes") % val().length()); - - val.ok = true; } inline void -verify_full(netsync_hmac_value & val) +verify(netsync_hmac_value & val) { if (val().size() == 0) { @@ -129,8 +106,6 @@ verify_full(netsync_hmac_value & val) N(val().size() == constants::netsync_hmac_value_length_in_bytes, F("Invalid hmac length of %d bytes") % val().length()); - - val.ok = true; } @@ -174,22 +149,25 @@ fake_id() #include "vocab_macros.hh" #define ENCODING(enc) cc_ENCODING(enc) +#define ENCODING_NOVERIFY(enc) cc_ENCODING_NOVERIFY(enc) #define DECORATE(dec) cc_DECORATE(dec) #define ATOMIC(ty) cc_ATOMIC(ty) +#define ATOMIC_HOOKED(ty,hook) cc_ATOMIC(ty) #define ATOMIC_NOVERIFY(ty) cc_ATOMIC_NOVERIFY(ty) -#ifdef EXTERN #undef EXTERN -#endif #define EXTERN #include "vocab_terms.hh" #undef EXTERN #undef ATOMIC +#undef ATOMIC_HOOKED +#undef ATOMIC_NOVERIFY #undef DECORATE +#undef ENCODING +#undef ENCODING_NOVERIFY - template void dump(rsa_pub_key const&, string &); ============================================================ --- vocab.hh c6a7cc514b64b15428fb5548a4deda1fc1a212b7 +++ vocab.hh 3a8c252a8f3f180aed8b200ee4a9c880ba51d915 @@ -51,8 +51,10 @@ public: #include "vocab_macros.hh" #define ENCODING(enc) hh_ENCODING(enc) +#define ENCODING_NOVERIFY(enc) hh_ENCODING_NOVERIFY(enc) #define DECORATE(dec) hh_DECORATE(dec) #define ATOMIC(ty) hh_ATOMIC(ty) +#define ATOMIC_HOOKED(ty,hook) hh_ATOMIC_HOOKED(ty,hook) #define ATOMIC_NOVERIFY(ty) hh_ATOMIC_NOVERIFY(ty) #ifdef HAVE_EXTERN_TEMPLATE @@ -64,9 +66,11 @@ public: #include "vocab_terms.hh" #undef ATOMIC +#undef ATOMIC_HOOKED #undef ATOMIC_NOVERIFY #undef DECORATE #undef ENCODING +#undef ENCODING_NOVERIFY // most of the time you want to use these typedefs and forget // about the stuff in vocab_terms.hh ============================================================ --- vocab_hash.hh 1bf71979cd58adf60349d0fb28459176c92f287b +++ vocab_hash.hh 4ec39d236ead9a0833db8bb8ad611a6188fbecb3 @@ -24,6 +24,7 @@ } \ }; \ } +#define ENCODING_NOVERIFY(enc) ENCODING(enc) #define DECORATE(dec) \ namespace hashmap { \ @@ -48,9 +49,16 @@ } \ }; \ } - +#define ATOMIC_HOOKED(ty,hook) ATOMIC(ty) #define ATOMIC_NOVERIFY(ty) ATOMIC(ty) #include "vocab_terms.hh" +#undef ENCODING +#undef ENCODING_NOVERIFY +#undef DECORATE +#undef ATOMIC +#undef ATOMIC_HOOKED +#undef ATOMIC_NOVERIFY + #endif ============================================================ --- vocab_macros.hh 7025028f87c647715e14fb50c13866e8df52d684 +++ vocab_macros.hh 27299229caa60ce0b18122ad5e03e17eb0f1f14f @@ -15,28 +15,28 @@ class enc { \ template \ class enc { \ - INNER i; \ + immutable_string s; \ public: \ - bool ok; \ - enc() : ok(false) {} \ + enc() {} \ explicit enc(std::string const & s); \ - explicit enc(INNER const & inner); \ enc(enc const & other); \ + enc const & \ + operator=(enc const & other); \ std::string const & operator()() const \ - { return i(); } \ + { return s.get(); } \ bool operator<(enc const & x) const \ - { return i() < x(); } \ - enc const & \ - operator=(enc const & other); \ + { return s.get() < x.s.get(); } \ bool operator==(enc const & x) const \ - { return i() == x(); } \ + { return s.get() == x.s.get(); } \ bool operator!=(enc const & x) const \ - { return !(i() == x()); } \ + { return s.get() != x.s.get(); } \ friend std::ostream & operator<< <>(std::ostream &, \ enc const &); \ }; +#define hh_ENCODING_NOVERIFY(enc) hh_ENCODING(enc) + #define hh_DECORATE(dec) \ \ template \ @@ -53,8 +53,7 @@ public: class dec { \ INNER i; \ public: \ - bool ok; \ - dec() : ok(false) {} \ + dec() {} \ explicit dec(std::string const & s); \ explicit dec(INNER const & inner); \ dec(dec const & other); \ @@ -73,42 +72,41 @@ public: }; -#define hh_ATOMIC(ty) \ +#define hh_ATOMIC_HOOKED(ty, hook) \ +class ty; \ + \ +std::ostream & operator<<(std::ostream &, ty const &); \ + \ +template <> \ +void dump(ty const &, std::string &); \ + \ class ty { \ immutable_string s; \ public: \ - bool ok; \ - ty() : ok(false) {} \ + ty() {} \ explicit ty(std::string const & str); \ ty(ty const & other); \ + ty const & operator=(ty const & other); \ std::string const & operator()() const \ { return s.get(); } \ - bool operator<(ty const & other) const \ - { return s.get() < other(); } \ - ty const & operator=(ty const & other); \ - bool operator==(ty const & other) const \ - { return s.get() == other(); } \ - bool operator!=(ty const & other) const \ - { return s.get() != other(); } \ - friend void verify(ty &); \ - friend void verify_full(ty &); \ + bool operator<(ty const & x) const \ + { return s.get() < x.s.get(); } \ + bool operator==(ty const & x) const \ + { return s.get() == x.s.get(); } \ + bool operator!=(ty const & x) const \ + { return s.get() != x.s.get(); } \ friend std::ostream & operator<<(std::ostream &, \ ty const &); \ + hook \ struct symtab \ { \ symtab(); \ ~symtab(); \ }; \ -}; \ -std::ostream & operator<<(std::ostream &, ty const &); \ -template <> \ -void dump(ty const &, std::string &); \ -inline void verify(ty &t) \ - { if(!t.ok) verify_full(t); }; +}; -#define hh_ATOMIC_NOVERIFY(ty) \ -ATOMIC(ty) \ -inline void verify_full(ty &) {} +#define hh_ATOMIC(ty) hh_ATOMIC_HOOKED(ty,) +#define hh_ATOMIC_NOVERIFY(ty) hh_ATOMIC(ty) //CC @@ -122,21 +120,17 @@ ty::ty(string const & str) : ty::ty(string const & str) : \ s((ty ## _tab_active > 0) \ ? (ty ## _tab.unique(str)) \ - : str), \ - ok(false) \ + : str) \ { verify(*this); } \ \ -ty::ty(ty const & other) : \ - s(other.s), ok(other.ok) \ -{ verify(*this); } \ +ty::ty(ty const & other) : s(other.s) {} \ \ ty const & ty::operator=(ty const & other) \ -{ s = other.s; ok = other.ok; \ - verify(*this); return *this; } \ +{ s = other.s; return *this; } \ \ - std::ostream & operator<<(std::ostream & o,\ - ty const & a) \ - { return (o << a.s.get()); } \ +std::ostream & operator<<(std::ostream & o, \ + ty const & a) \ +{ return (o << a.s.get()); } \ \ template <> \ void dump(ty const & obj, std::string & out) \ @@ -154,61 +148,61 @@ ty::symtab::~symtab() } -#define cc_ATOMIC_NOVERIFY(ty) cc_ATOMIC(ty) +#define cc_ATOMIC_NOVERIFY(ty) \ +inline void verify(ty const &) {} \ +cc_ATOMIC(ty) #define cc_ENCODING(enc) \ \ template \ -enc::enc(string const & s) : i(s), ok(false) \ +enc::enc(string const & s) : s(s) \ { verify(*this); } \ \ template \ enc::enc(enc const & other) \ - : i(other.i), ok(other.ok) { verify(*this); } \ + : s(other.s) {} \ \ template \ -enc::enc(INNER const & inner) : \ - i(inner), ok(false) \ - { verify(*this); } \ - \ -template \ enc const & \ enc::operator=(enc const & other) \ - { i = other.i; ok = other.ok; \ - verify(*this); return *this;} \ + { s = other.s; return *this; } \ \ template \ std::ostream & operator<<(std::ostream & o, \ enc const & e) \ -{ return (o << e.i); } \ +{ return (o << e.s.get()); } \ \ template \ void dump(enc const & obj, std::string & out) \ { out = obj(); } +#define cc_ENCODING_NOVERIFY(enc) \ +template \ +inline void verify(enc const &) {} \ +cc_ENCODING(enc) + + #define cc_DECORATE(dec) \ \ template \ dec::dec(dec const & other) \ - : i(other.i), ok(other.ok) { verify(*this); } \ + : i(other.i) {} \ \ template \ dec::dec(std::string const & s) \ - : i(s), ok(false) { verify(*this); } \ + : i(s) { verify(i); } \ \ template \ -dec::dec(INNER const & inner) : \ - i(inner), ok(false) \ - { verify(*this); } \ +dec::dec(INNER const & inner) \ + : i(inner) {} \ \ template \ dec const & \ dec::operator=(dec const & other) \ - { i = other.i; ok = other.ok; \ - verify(*this); return *this;} \ + { i = other.i; return *this; } \ \ template \ std::ostream & operator<<(std::ostream & o, \ @@ -220,9 +214,6 @@ void dump(dec const & obj, std::s { dump(obj.inner(), out); } - - - // Local Variables: // mode: C++ // fill-column: 76 ============================================================ --- vocab_terms.hh 80283d95bc08f3a9f8c1c503ebeebb51b03c384e +++ vocab_terms.hh c35150005f1e928769604620caa4e894416a3265 @@ -40,9 +40,16 @@ ATOMIC_NOVERIFY(rsa_oaep_sha_data); ATOMIC_NOVERIFY(rsa_sha1_signature); // some other nice numbers ATOMIC_NOVERIFY(rsa_oaep_sha_data); -ATOMIC(netsync_session_key); // key for netsync session HMAC -ATOMIC(netsync_hmac_value); // 160-bit SHA-1 HMAC +// Special case: these classes need to befriend their verify functions. +// See vocab.cc for details. +// key for netsync session HMAC +ATOMIC_HOOKED(netsync_session_key, + friend void verify(netsync_session_key &);); +// 160-bit SHA-1 HMAC +ATOMIC_HOOKED(netsync_hmac_value, + friend void verify(netsync_hmac_value &);); + ATOMIC_NOVERIFY(attr_key); ATOMIC_NOVERIFY(attr_value); @@ -53,9 +60,9 @@ DECORATE(epoch); // thing a DECORATE(key); // thing associated with a key DECORATE(epoch); // thing associated with an epoch -ENCODING(gzip); // thing which is gzipped +ENCODING_NOVERIFY(gzip); // thing which is gzipped ENCODING(hexenc); // thing which is hex-encoded -ENCODING(base64); // thing which is base64-encoded +ENCODING_NOVERIFY(base64); // thing which is base64-encoded ATOMIC_NOVERIFY(prefix); // raw encoding of a merkle tree prefix ATOMIC_NOVERIFY(merkle); // raw encoding of a merkle tree node