diff --git a/extra/yassl/include/factory.hpp b/extra/yassl/include/factory.hpp index 96798466352..7f7aaf8bd7f 100644 --- a/extra/yassl/include/factory.hpp +++ b/extra/yassl/include/factory.hpp @@ -67,7 +67,7 @@ public: init(*this); } - // reservce place in vector before registering, used by init funcion + // reserve place in vector before registering, used by init funcion void Reserve(size_t sz) { callbacks_.reserve(sz); diff --git a/extra/yassl/include/yassl_int.hpp b/extra/yassl/include/yassl_int.hpp index 02895d3897b..c9168254907 100644 --- a/extra/yassl/include/yassl_int.hpp +++ b/extra/yassl/include/yassl_int.hpp @@ -31,8 +31,8 @@ #include "yassl_imp.hpp" #include "crypto_wrapper.hpp" #include "cert_wrapper.hpp" -#include "lock.hpp" #include "log.hpp" +#include "lock.hpp" namespace yaSSL { diff --git a/extra/yassl/include/yassl_types.hpp b/extra/yassl/include/yassl_types.hpp index 1ad4998bade..28f673f920d 100644 --- a/extra/yassl/include/yassl_types.hpp +++ b/extra/yassl/include/yassl_types.hpp @@ -29,16 +29,6 @@ #include -namespace yaSSL { - -// library allocation -struct new_t {}; // yaSSL New type -extern new_t ys; // pass in parameter - -} // namespace yaSSL - -void* operator new (size_t, yaSSL::new_t); -void* operator new[](size_t, yaSSL::new_t); namespace yaSSL { diff --git a/extra/yassl/src/buffer.cpp b/extra/yassl/src/buffer.cpp index c97103c6f6d..6dc8845559c 100644 --- a/extra/yassl/src/buffer.cpp +++ b/extra/yassl/src/buffer.cpp @@ -62,13 +62,13 @@ input_buffer::input_buffer() input_buffer::input_buffer(uint s) - : size_(0), current_(0), buffer_(new (ys) byte[s]), end_(buffer_ + s) + : size_(0), current_(0), buffer_(new byte[s]), end_(buffer_ + s) {} // with assign input_buffer::input_buffer(uint s, const byte* t, uint len) - : size_(0), current_(0), buffer_(new (ys) byte[s]), end_(buffer_ + s) + : size_(0), current_(0), buffer_(new byte[s]), end_(buffer_ + s) { assign(t, len); } @@ -84,7 +84,7 @@ input_buffer::~input_buffer() void input_buffer::allocate(uint s) { assert(!buffer_); // find realloc error - buffer_ = new (ys) byte[s]; + buffer_ = new byte[s]; end_ = buffer_ + s; } @@ -198,13 +198,13 @@ output_buffer::output_buffer() // with allocate output_buffer::output_buffer(uint s) - : current_(0), buffer_(new (ys) byte[s]), end_(buffer_ + s) + : current_(0), buffer_(new byte[s]), end_(buffer_ + s) {} // with assign output_buffer::output_buffer(uint s, const byte* t, uint len) - : current_(0), buffer_(new (ys) byte[s]), end_(buffer_+ s) + : current_(0), buffer_(new byte[s]), end_(buffer_+ s) { write(t, len); } @@ -239,7 +239,7 @@ void output_buffer::set_current(uint c) void output_buffer::allocate(uint s) { assert(!buffer_); // find realloc error - buffer_ = new (ys) byte[s]; end_ = buffer_ + s; + buffer_ = new byte[s]; end_ = buffer_ + s; } diff --git a/extra/yassl/src/cert_wrapper.cpp b/extra/yassl/src/cert_wrapper.cpp index 98861d01287..33c1fee6ec3 100644 --- a/extra/yassl/src/cert_wrapper.cpp +++ b/extra/yassl/src/cert_wrapper.cpp @@ -39,7 +39,7 @@ namespace yaSSL { -x509::x509(uint sz) : length_(sz), buffer_(new (ys) opaque[sz]) +x509::x509(uint sz) : length_(sz), buffer_(new opaque[sz]) { } @@ -51,7 +51,7 @@ x509::~x509() x509::x509(const x509& that) : length_(that.length_), - buffer_(new (ys) opaque[length_]) + buffer_(new opaque[length_]) { memcpy(buffer_, that.buffer_, length_); } @@ -153,7 +153,7 @@ void CertManager::AddPeerCert(x509* x) void CertManager::CopySelfCert(const x509* x) { if (x) - list_.push_back(new (ys) x509(*x)); + list_.push_back(new x509(*x)); } @@ -165,7 +165,7 @@ int CertManager::CopyCaCert(const x509* x) if (!cert.GetError().What()) { const TaoCrypt::PublicKey& key = cert.GetPublicKey(); - signers_.push_back(new (ys) TaoCrypt::Signer(key.GetKey(), key.size(), + signers_.push_back(new TaoCrypt::Signer(key.GetKey(), key.size(), cert.GetCommonName(), cert.GetHash())); } return cert.GetError().What(); @@ -234,7 +234,7 @@ int CertManager::Validate() return err; const TaoCrypt::PublicKey& key = cert.GetPublicKey(); - signers_.push_back(new (ys) TaoCrypt::Signer(key.GetKey(), key.size(), + signers_.push_back(new TaoCrypt::Signer(key.GetKey(), key.size(), cert.GetCommonName(), cert.GetHash())); --last; --count; @@ -259,7 +259,7 @@ int CertManager::Validate() int iSz = cert.GetIssuer() ? strlen(cert.GetIssuer()) + 1 : 0; int sSz = cert.GetCommonName() ? strlen(cert.GetCommonName()) + 1 : 0; - peerX509_ = new (ys) X509(cert.GetIssuer(), iSz, cert.GetCommonName(), + peerX509_ = new X509(cert.GetIssuer(), iSz, cert.GetCommonName(), sSz); } return 0; @@ -273,13 +273,13 @@ int CertManager::SetPrivateKey(const x509& key) privateKey_.assign(key.get_buffer(), key.get_length()); // set key type - if (x509* cert509 = list_.front()) { - TaoCrypt::Source source(cert509->get_buffer(), cert509->get_length()); - TaoCrypt::CertDecoder cert(source, false); - cert.DecodeToKey(); - if (int err = cert.GetError().What()) + if (x509* cert = list_.front()) { + TaoCrypt::Source source(cert->get_buffer(), cert->get_length()); + TaoCrypt::CertDecoder cd(source, false); + cd.DecodeToKey(); + if (int err = cd.GetError().What()) return err; - if (cert.GetKeyType() == TaoCrypt::RSAk) + if (cd.GetKeyType() == TaoCrypt::RSAk) keyType_ = rsa_sa_algo; else keyType_ = dsa_sa_algo; diff --git a/extra/yassl/src/crypto_wrapper.cpp b/extra/yassl/src/crypto_wrapper.cpp index c083c56f313..e6b28cd9302 100644 --- a/extra/yassl/src/crypto_wrapper.cpp +++ b/extra/yassl/src/crypto_wrapper.cpp @@ -58,13 +58,13 @@ struct MD5::MD5Impl { }; -MD5::MD5() : pimpl_(new (ys) MD5Impl) {} +MD5::MD5() : pimpl_(new MD5Impl) {} MD5::~MD5() { delete pimpl_; } -MD5::MD5(const MD5& that) : Digest(), pimpl_(new (ys) +MD5::MD5(const MD5& that) : Digest(), pimpl_(new MD5Impl(that.pimpl_->md5_)) {} @@ -116,14 +116,13 @@ struct SHA::SHAImpl { }; -SHA::SHA() : pimpl_(new (ys) SHAImpl) {} +SHA::SHA() : pimpl_(new SHAImpl) {} SHA::~SHA() { delete pimpl_; } -SHA::SHA(const SHA& that) : Digest(), pimpl_(new (ys) - SHAImpl(that.pimpl_->sha_)) {} +SHA::SHA(const SHA& that) : Digest(), pimpl_(new SHAImpl(that.pimpl_->sha_)) {} SHA& SHA::operator=(const SHA& that) { @@ -174,14 +173,13 @@ struct RMD::RMDImpl { }; -RMD::RMD() : pimpl_(new (ys) RMDImpl) {} +RMD::RMD() : pimpl_(new RMDImpl) {} RMD::~RMD() { delete pimpl_; } -RMD::RMD(const RMD& that) : Digest(), pimpl_(new (ys) - RMDImpl(that.pimpl_->rmd_)) {} +RMD::RMD(const RMD& that) : Digest(), pimpl_(new RMDImpl(that.pimpl_->rmd_)) {} RMD& RMD::operator=(const RMD& that) { @@ -232,7 +230,7 @@ struct HMAC_MD5::HMAC_MD5Impl { HMAC_MD5::HMAC_MD5(const byte* secret, unsigned int len) - : pimpl_(new (ys) HMAC_MD5Impl) + : pimpl_(new HMAC_MD5Impl) { pimpl_->mac_.SetKey(secret, len); } @@ -282,7 +280,7 @@ struct HMAC_SHA::HMAC_SHAImpl { HMAC_SHA::HMAC_SHA(const byte* secret, unsigned int len) - : pimpl_(new (ys) HMAC_SHAImpl) + : pimpl_(new HMAC_SHAImpl) { pimpl_->mac_.SetKey(secret, len); } @@ -333,7 +331,7 @@ struct HMAC_RMD::HMAC_RMDImpl { HMAC_RMD::HMAC_RMD(const byte* secret, unsigned int len) - : pimpl_(new (ys) HMAC_RMDImpl) + : pimpl_(new HMAC_RMDImpl) { pimpl_->mac_.SetKey(secret, len); } @@ -381,7 +379,7 @@ struct DES::DESImpl { }; -DES::DES() : pimpl_(new (ys) DESImpl) {} +DES::DES() : pimpl_(new DESImpl) {} DES::~DES() { delete pimpl_; } @@ -417,7 +415,7 @@ struct DES_EDE::DES_EDEImpl { }; -DES_EDE::DES_EDE() : pimpl_(new (ys) DES_EDEImpl) {} +DES_EDE::DES_EDE() : pimpl_(new DES_EDEImpl) {} DES_EDE::~DES_EDE() { delete pimpl_; } @@ -455,7 +453,7 @@ struct RC4::RC4Impl { }; -RC4::RC4() : pimpl_(new (ys) RC4Impl) {} +RC4::RC4() : pimpl_(new RC4Impl) {} RC4::~RC4() { delete pimpl_; } @@ -497,7 +495,7 @@ struct AES::AESImpl { }; -AES::AES(unsigned int ks) : pimpl_(new (ys) AESImpl(ks)) {} +AES::AES(unsigned int ks) : pimpl_(new AESImpl(ks)) {} AES::~AES() { delete pimpl_; } @@ -538,7 +536,7 @@ struct RandomPool::RandomImpl { TaoCrypt::RandomNumberGenerator RNG_; }; -RandomPool::RandomPool() : pimpl_(new (ys) RandomImpl) {} +RandomPool::RandomPool() : pimpl_(new RandomImpl) {} RandomPool::~RandomPool() { delete pimpl_; } @@ -582,7 +580,7 @@ void DSS::DSSImpl::SetPrivate(const byte* key, unsigned int sz) // Set public or private key DSS::DSS(const byte* key, unsigned int sz, bool publicKey) - : pimpl_(new (ys) DSSImpl) + : pimpl_(new DSSImpl) { if (publicKey) pimpl_->SetPublic(key, sz); @@ -653,7 +651,7 @@ void RSA::RSAImpl::SetPrivate(const byte* key, unsigned int sz) // Set public or private key RSA::RSA(const byte* key, unsigned int sz, bool publicKey) - : pimpl_(new (ys) RSAImpl) + : pimpl_(new RSAImpl) { if (publicKey) pimpl_->SetPublic(key, sz); @@ -725,13 +723,13 @@ struct Integer::IntegerImpl { explicit IntegerImpl(const TaoCrypt::Integer& i) : int_(i) {} }; -Integer::Integer() : pimpl_(new (ys) IntegerImpl) {} +Integer::Integer() : pimpl_(new IntegerImpl) {} Integer::~Integer() { delete pimpl_; } -Integer::Integer(const Integer& other) : pimpl_(new (ys) +Integer::Integer(const Integer& other) : pimpl_(new IntegerImpl(other.pimpl_->int_)) {} @@ -770,9 +768,9 @@ struct DiffieHellman::DHImpl { void AllocKeys(unsigned int pubSz, unsigned int privSz, unsigned int agrSz) { - publicKey_ = new (ys) byte[pubSz]; - privateKey_ = new (ys) byte[privSz]; - agreedKey_ = new (ys) byte[agrSz]; + publicKey_ = new byte[pubSz]; + privateKey_ = new byte[privSz]; + agreedKey_ = new byte[agrSz]; } }; @@ -781,7 +779,7 @@ struct DiffieHellman::DHImpl { /* // server Side DH, server's view DiffieHellman::DiffieHellman(const char* file, const RandomPool& random) - : pimpl_(new (ys) DHImpl(random.pimpl_->RNG_)) + : pimpl_(new DHImpl(random.pimpl_->RNG_)) { using namespace TaoCrypt; Source source; @@ -805,12 +803,12 @@ DiffieHellman::DiffieHellman(const char* file, const RandomPool& random) DiffieHellman::DiffieHellman(const byte* p, unsigned int pSz, const byte* g, unsigned int gSz, const byte* pub, unsigned int pubSz, const RandomPool& random) - : pimpl_(new (ys) DHImpl(random.pimpl_->RNG_)) + : pimpl_(new DHImpl(random.pimpl_->RNG_)) { using TaoCrypt::Integer; pimpl_->dh_.Initialize(Integer(p, pSz).Ref(), Integer(g, gSz).Ref()); - pimpl_->publicKey_ = new (ys) opaque[pubSz]; + pimpl_->publicKey_ = new opaque[pubSz]; memcpy(pimpl_->publicKey_, pub, pubSz); } @@ -818,7 +816,7 @@ DiffieHellman::DiffieHellman(const byte* p, unsigned int pSz, const byte* g, // Server Side DH, server's view DiffieHellman::DiffieHellman(const Integer& p, const Integer& g, const RandomPool& random) -: pimpl_(new (ys) DHImpl(random.pimpl_->RNG_)) +: pimpl_(new DHImpl(random.pimpl_->RNG_)) { using TaoCrypt::Integer; @@ -836,7 +834,7 @@ DiffieHellman::~DiffieHellman() { delete pimpl_; } // Client side and view, use server that for p and g DiffieHellman::DiffieHellman(const DiffieHellman& that) - : pimpl_(new (ys) DHImpl(*that.pimpl_)) + : pimpl_(new DHImpl(*that.pimpl_)) { pimpl_->dh_.GenerateKeyPair(pimpl_->ranPool_, pimpl_->privateKey_, pimpl_->publicKey_); @@ -957,7 +955,7 @@ x509* PemToDer(const char* fname, CertType type) Base64Decoder b64Dec(der); uint sz = der.size(); - mySTL::auto_ptr x(new (ys) x509(sz)); + mySTL::auto_ptr x(new x509(sz)); memcpy(x->use_buffer(), der.get_buffer(), sz); fclose(file); @@ -971,8 +969,6 @@ x509* PemToDer(const char* fname, CertType type) template class TaoCrypt::HMAC; template class TaoCrypt::HMAC; template class TaoCrypt::HMAC; -template class TaoCrypt::Mode_BASE<16>; -template class TaoCrypt::Mode_BASE<8>; #endif #endif // !USE_CRYPTOPP_LIB diff --git a/extra/yassl/src/handshake.cpp b/extra/yassl/src/handshake.cpp index 35c4cbd4922..28872e50063 100644 --- a/extra/yassl/src/handshake.cpp +++ b/extra/yassl/src/handshake.cpp @@ -362,9 +362,9 @@ void p_hash(output_buffer& result, const output_buffer& secret, if (lastLen) times += 1; if (hash == md5) - hmac.reset(new (ys) HMAC_MD5(secret.get_buffer(), secret.get_size())); + hmac.reset(new HMAC_MD5(secret.get_buffer(), secret.get_size())); else - hmac.reset(new (ys) HMAC_SHA(secret.get_buffer(), secret.get_size())); + hmac.reset(new HMAC_SHA(secret.get_buffer(), secret.get_size())); // A0 = seed hmac->get_digest(previous, seed.get_buffer(), seed.get_size());// A1 uint lastTime = times - 1; @@ -582,11 +582,11 @@ void TLS_hmac(SSL& ssl, byte* digest, const byte* buffer, uint sz, MACAlgorithm algo = ssl.getSecurity().get_parms().mac_algorithm_; if (algo == sha) - hmac.reset(new (ys) HMAC_SHA(ssl.get_macSecret(verify), SHA_LEN)); + hmac.reset(new HMAC_SHA(ssl.get_macSecret(verify), SHA_LEN)); else if (algo == rmd) - hmac.reset(new (ys) HMAC_RMD(ssl.get_macSecret(verify), RMD_LEN)); + hmac.reset(new HMAC_RMD(ssl.get_macSecret(verify), RMD_LEN)); else - hmac.reset(new (ys) HMAC_MD5(ssl.get_macSecret(verify), MD5_LEN)); + hmac.reset(new HMAC_MD5(ssl.get_macSecret(verify), MD5_LEN)); hmac->update(seq, SEQ_SZ); // seq_num inner[0] = content; // type @@ -687,7 +687,7 @@ DoProcessReply(SSL& ssl, mySTL::auto_ptr buffered) // make sure we have enough input in buffer to process this record if (hdr.length_ > buffer.get_remaining()) { uint sz = buffer.get_remaining() + RECORD_HEADER; - buffered.reset(new (ys) input_buffer(sz, buffer.get_buffer() + + buffered.reset(new input_buffer(sz, buffer.get_buffer() + buffer.get_current() - RECORD_HEADER, sz)); break; } @@ -760,7 +760,7 @@ void sendClientKeyExchange(SSL& ssl, BufferOutput buffer) RecordLayerHeader rlHeader; HandShakeHeader hsHeader; - mySTL::auto_ptr out(new (ys) output_buffer); + mySTL::auto_ptr out(new output_buffer); buildHeaders(ssl, hsHeader, rlHeader, ck); buildOutput(*out.get(), rlHeader, hsHeader, ck); hashHandShake(ssl, *out.get()); @@ -781,7 +781,7 @@ void sendServerKeyExchange(SSL& ssl, BufferOutput buffer) RecordLayerHeader rlHeader; HandShakeHeader hsHeader; - mySTL::auto_ptr out(new (ys) output_buffer); + mySTL::auto_ptr out(new output_buffer); buildHeaders(ssl, hsHeader, rlHeader, sk); buildOutput(*out.get(), rlHeader, hsHeader, sk); hashHandShake(ssl, *out.get()); @@ -806,7 +806,7 @@ void sendChangeCipher(SSL& ssl, BufferOutput buffer) ChangeCipherSpec ccs; RecordLayerHeader rlHeader; buildHeader(ssl, rlHeader, ccs); - mySTL::auto_ptr out(new (ys) output_buffer); + mySTL::auto_ptr out(new output_buffer); buildOutput(*out.get(), rlHeader, ccs); if (buffer == buffered) @@ -823,7 +823,7 @@ void sendFinished(SSL& ssl, ConnectionEnd side, BufferOutput buffer) Finished fin; buildFinished(ssl, fin, side == client_end ? client : server); - mySTL::auto_ptr out(new (ys) output_buffer); + mySTL::auto_ptr out(new output_buffer); cipherFinished(ssl, fin, *out.get()); // hashes handshake if (ssl.getSecurity().get_resuming()) { @@ -907,7 +907,7 @@ void sendServerHello(SSL& ssl, BufferOutput buffer) ServerHello sh(ssl.getSecurity().get_connection().version_); RecordLayerHeader rlHeader; HandShakeHeader hsHeader; - mySTL::auto_ptr out(new (ys) output_buffer); + mySTL::auto_ptr out(new output_buffer); buildServerHello(ssl, sh); ssl.set_random(sh.get_random(), server_end); @@ -930,7 +930,7 @@ void sendServerHelloDone(SSL& ssl, BufferOutput buffer) ServerHelloDone shd; RecordLayerHeader rlHeader; HandShakeHeader hsHeader; - mySTL::auto_ptr out(new (ys) output_buffer); + mySTL::auto_ptr out(new output_buffer); buildHeaders(ssl, hsHeader, rlHeader, shd); buildOutput(*out.get(), rlHeader, hsHeader, shd); @@ -951,7 +951,7 @@ void sendCertificate(SSL& ssl, BufferOutput buffer) Certificate cert(ssl.getCrypto().get_certManager().get_cert()); RecordLayerHeader rlHeader; HandShakeHeader hsHeader; - mySTL::auto_ptr out(new (ys) output_buffer); + mySTL::auto_ptr out(new output_buffer); buildHeaders(ssl, hsHeader, rlHeader, cert); buildOutput(*out.get(), rlHeader, hsHeader, cert); @@ -973,7 +973,7 @@ void sendCertificateRequest(SSL& ssl, BufferOutput buffer) request.Build(); RecordLayerHeader rlHeader; HandShakeHeader hsHeader; - mySTL::auto_ptr out(new (ys) output_buffer); + mySTL::auto_ptr out(new output_buffer); buildHeaders(ssl, hsHeader, rlHeader, request); buildOutput(*out.get(), rlHeader, hsHeader, request); @@ -995,7 +995,7 @@ void sendCertificateVerify(SSL& ssl, BufferOutput buffer) verify.Build(ssl); RecordLayerHeader rlHeader; HandShakeHeader hsHeader; - mySTL::auto_ptr out(new (ys) output_buffer); + mySTL::auto_ptr out(new output_buffer); buildHeaders(ssl, hsHeader, rlHeader, verify); buildOutput(*out.get(), rlHeader, hsHeader, verify); diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp index 53bd8a75ab6..b0d9dcca902 100644 --- a/extra/yassl/src/ssl.cpp +++ b/extra/yassl/src/ssl.cpp @@ -443,7 +443,7 @@ int read_file(SSL_CTX* ctx, const char* file, int format, CertType type) fseek(input, 0, SEEK_END); long sz = ftell(input); rewind(input); - x = new (ys) x509(sz); // takes ownership + x = new x509(sz); // takes ownership size_t bytes = fread(x->use_buffer(), sz, 1, input); if (bytes != 1) { fclose(input); @@ -663,7 +663,7 @@ BIGNUM* BN_bin2bn(const unsigned char* num, int sz, BIGNUM* retVal) if (!retVal) { created = true; - bn.reset(new (ys) BIGNUM); + bn.reset(new BIGNUM); retVal = bn.get(); } diff --git a/extra/yassl/src/yassl_imp.cpp b/extra/yassl/src/yassl_imp.cpp index c1485cce986..02654727f78 100644 --- a/extra/yassl/src/yassl_imp.cpp +++ b/extra/yassl/src/yassl_imp.cpp @@ -134,10 +134,10 @@ void DH_Server::build(SSL& ssl) const CertManager& cert = ssl.getCrypto().get_certManager(); if (ssl.getSecurity().get_parms().sig_algo_ == rsa_sa_algo) - auth.reset(new (ys) RSA(cert.get_privateKey(), + auth.reset(new RSA(cert.get_privateKey(), cert.get_privateKeyLength(), false)); else { - auth.reset(new (ys) DSS(cert.get_privateKey(), + auth.reset(new DSS(cert.get_privateKey(), cert.get_privateKeyLength(), false)); sigSz += DSS_ENCODED_EXTRA; } @@ -168,7 +168,7 @@ void DH_Server::build(SSL& ssl) byte hash[FINISHED_SZ]; MD5 md5; SHA sha; - signature_ = new (ys) byte[sigSz]; + signature_ = new byte[sigSz]; const Connection& conn = ssl.getSecurity().get_connection(); // md5 @@ -199,7 +199,7 @@ void DH_Server::build(SSL& ssl) tmp.write(signature_, sigSz); // key message - keyMessage_ = new (ys) opaque[length_]; + keyMessage_ = new opaque[length_]; memcpy(keyMessage_, tmp.get_buffer(), tmp.get_size()); } @@ -253,7 +253,7 @@ opaque* EncryptedPreMasterSecret::get_clientKey() const void EncryptedPreMasterSecret::alloc(int sz) { length_ = sz; - secret_ = new (ys) opaque[sz]; + secret_ = new opaque[sz]; } @@ -303,7 +303,7 @@ opaque* ClientDiffieHellmanPublic::get_clientKey() const void ClientDiffieHellmanPublic::alloc(int sz, bool offset) { length_ = sz + (offset ? KEY_OFFSET : 0); - Yc_ = new (ys) opaque[length_]; + Yc_ = new opaque[length_]; } @@ -348,7 +348,7 @@ void DH_Server::read(SSL& ssl, input_buffer& input) tmp[1] = input[AUTO]; ato16(tmp, length); - signature_ = new (ys) byte[length]; + signature_ = new byte[length]; input.read(signature_, length); // verify signature @@ -386,7 +386,7 @@ void DH_Server::read(SSL& ssl, input_buffer& input) } // save input - ssl.useCrypto().SetDH(new (ys) DiffieHellman(parms_.get_p(), + ssl.useCrypto().SetDH(new DiffieHellman(parms_.get_p(), parms_.get_pSize(), parms_.get_g(), parms_.get_gSize(), parms_.get_pub(), parms_.get_pubSize(), ssl.getCrypto().get_random())); @@ -928,7 +928,7 @@ void Data::Process(input_buffer& input, SSL& ssl) // read data if (dataSz) { input_buffer* data; - ssl.addData(data = new (ys) input_buffer(dataSz)); + ssl.addData(data = new input_buffer(dataSz)); input.read(data->get_buffer(), dataSz); data->add_size(dataSz); @@ -1025,7 +1025,7 @@ void Certificate::Process(input_buffer& input, SSL& ssl) c24to32(tmp, cert_sz); x509* myCert; - cm.AddPeerCert(myCert = new (ys) x509(cert_sz)); + cm.AddPeerCert(myCert = new x509(cert_sz)); input.read(myCert->use_buffer(), myCert->get_length()); list_sz -= cert_sz + CERT_HEADER; @@ -1111,21 +1111,21 @@ const opaque* ServerDHParams::get_pub() const opaque* ServerDHParams::alloc_p(int sz) { - p_ = new (ys) opaque[pSz_ = sz]; + p_ = new opaque[pSz_ = sz]; return p_; } opaque* ServerDHParams::alloc_g(int sz) { - g_ = new (ys) opaque[gSz_ = sz]; + g_ = new opaque[gSz_ = sz]; return g_; } opaque* ServerDHParams::alloc_pub(int sz) { - Ys_ = new (ys) opaque[pubSz_ = sz]; + Ys_ = new opaque[pubSz_ = sz]; return Ys_; } @@ -1537,7 +1537,7 @@ void CertificateRequest::Build() for (int j = 0; j < authCount; j++) { int sz = REQUEST_HEADER + MIN_DIS_SIZE; DistinguishedName dn; - certificate_authorities_.push_back(dn = new (ys) byte[sz]); + certificate_authorities_.push_back(dn = new byte[sz]); opaque tmp[REQUEST_HEADER]; c16toa(MIN_DIS_SIZE, tmp); @@ -1584,7 +1584,7 @@ input_buffer& operator>>(input_buffer& input, CertificateRequest& request) ato16(tmp, dnSz); DistinguishedName dn; - request.certificate_authorities_.push_back(dn = new (ys) + request.certificate_authorities_.push_back(dn = new byte[REQUEST_HEADER + dnSz]); memcpy(dn, tmp, REQUEST_HEADER); input.read(&dn[REQUEST_HEADER], dnSz); @@ -1665,7 +1665,7 @@ void CertificateVerify::Build(SSL& ssl) RSA rsa(cert.get_privateKey(), cert.get_privateKeyLength(), false); sz = rsa.get_cipherLength() + VERIFY_HEADER; - sig.reset(new (ys) byte[sz]); + sig.reset(new byte[sz]); c16toa(sz - VERIFY_HEADER, len); memcpy(sig.get(), len, VERIFY_HEADER); @@ -1676,7 +1676,7 @@ void CertificateVerify::Build(SSL& ssl) DSS dss(cert.get_privateKey(), cert.get_privateKeyLength(), false); sz = DSS_SIG_SZ + DSS_ENCODED_EXTRA + VERIFY_HEADER; - sig.reset(new (ys) byte[sz]); + sig.reset(new byte[sz]); c16toa(sz - VERIFY_HEADER, len); memcpy(sig.get(), len, VERIFY_HEADER); @@ -1714,7 +1714,7 @@ input_buffer& operator>>(input_buffer& input, CertificateVerify& request) ato16(tmp, sz); request.set_length(sz); - request.signature_ = new (ys) byte[sz]; + request.signature_ = new byte[sz]; input.read(request.signature_, sz); return input; @@ -1975,7 +1975,7 @@ Connection::~Connection() void Connection::AllocPreSecret(uint sz) { - pre_master_secret_ = new (ys) opaque[pre_secret_len_ = sz]; + pre_master_secret_ = new opaque[pre_secret_len_ = sz]; } @@ -2011,35 +2011,35 @@ void Connection::CleanPreMaster() // Create functions for message factory -Message* CreateCipherSpec() { return new (ys) ChangeCipherSpec; } -Message* CreateAlert() { return new (ys) Alert; } -Message* CreateHandShake() { return new (ys) HandShakeHeader; } -Message* CreateData() { return new (ys) Data; } +Message* CreateCipherSpec() { return new ChangeCipherSpec; } +Message* CreateAlert() { return new Alert; } +Message* CreateHandShake() { return new HandShakeHeader; } +Message* CreateData() { return new Data; } // Create functions for handshake factory -HandShakeBase* CreateHelloRequest() { return new (ys) HelloRequest; } -HandShakeBase* CreateClientHello() { return new (ys) ClientHello; } -HandShakeBase* CreateServerHello() { return new (ys) ServerHello; } -HandShakeBase* CreateCertificate() { return new (ys) Certificate; } -HandShakeBase* CreateServerKeyExchange() { return new (ys) ServerKeyExchange;} -HandShakeBase* CreateCertificateRequest() { return new (ys) +HandShakeBase* CreateHelloRequest() { return new HelloRequest; } +HandShakeBase* CreateClientHello() { return new ClientHello; } +HandShakeBase* CreateServerHello() { return new ServerHello; } +HandShakeBase* CreateCertificate() { return new Certificate; } +HandShakeBase* CreateServerKeyExchange() { return new ServerKeyExchange;} +HandShakeBase* CreateCertificateRequest() { return new CertificateRequest; } -HandShakeBase* CreateServerHelloDone() { return new (ys) ServerHelloDone; } -HandShakeBase* CreateCertificateVerify() { return new (ys) CertificateVerify;} -HandShakeBase* CreateClientKeyExchange() { return new (ys) ClientKeyExchange;} -HandShakeBase* CreateFinished() { return new (ys) Finished; } +HandShakeBase* CreateServerHelloDone() { return new ServerHelloDone; } +HandShakeBase* CreateCertificateVerify() { return new CertificateVerify;} +HandShakeBase* CreateClientKeyExchange() { return new ClientKeyExchange;} +HandShakeBase* CreateFinished() { return new Finished; } // Create functions for server key exchange factory -ServerKeyBase* CreateRSAServerKEA() { return new (ys) RSA_Server; } -ServerKeyBase* CreateDHServerKEA() { return new (ys) DH_Server; } -ServerKeyBase* CreateFortezzaServerKEA() { return new (ys) Fortezza_Server; } +ServerKeyBase* CreateRSAServerKEA() { return new RSA_Server; } +ServerKeyBase* CreateDHServerKEA() { return new DH_Server; } +ServerKeyBase* CreateFortezzaServerKEA() { return new Fortezza_Server; } // Create functions for client key exchange factory -ClientKeyBase* CreateRSAClient() { return new (ys) +ClientKeyBase* CreateRSAClient() { return new EncryptedPreMasterSecret; } -ClientKeyBase* CreateDHClient() { return new (ys) +ClientKeyBase* CreateDHClient() { return new ClientDiffieHellmanPublic; } -ClientKeyBase* CreateFortezzaClient() { return new (ys) FortezzaKeys; } +ClientKeyBase* CreateFortezzaClient() { return new FortezzaKeys; } // Constructor calls this to Register compile time callbacks @@ -2115,4 +2115,3 @@ template yaSSL::del_ptr_zero mySTL::for_each: template yaSSL::del_ptr_zero mySTL::for_each::iterator, yaSSL::del_ptr_zero>(mySTL::list::iterator, mySTL::list::iterator, yaSSL::del_ptr_zero); } #endif - diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp index c552cfa7189..f32a8420b98 100644 --- a/extra/yassl/src/yassl_int.cpp +++ b/extra/yassl/src/yassl_int.cpp @@ -31,28 +31,6 @@ #include "openssl/ssl.h" // for DH -void* operator new(size_t sz, yaSSL::new_t) -{ - void* ptr = ::operator new(sz); - - if (!ptr) abort(); - - return ptr; -} - -void* operator new[](size_t sz, yaSSL::new_t n) -{ -#if defined(_MSC_VER) && (_MSC_VER < 1300) - void* ptr = ::operator new(sz); // no ::operator new[] -#else - void* ptr = ::operator new[](sz); -#endif - - if (!ptr) abort(); - - return ptr; -} - namespace yaSSL { @@ -60,8 +38,6 @@ namespace yaSSL { using mySTL::min; -new_t ys; // for library new - // convert a 32 bit integer into a 24 bit one void c32to24(uint32 u32, uint24& u24) @@ -308,8 +284,8 @@ void SSL::set_pending(Cipher suite) parms.key_size_ = AES_256_KEY_SZ; parms.iv_size_ = AES_BLOCK_SZ; parms.cipher_type_ = block; - crypto_.setDigest(new (ys) SHA); - crypto_.setCipher(new (ys) AES(AES_256_KEY_SZ)); + crypto_.setDigest(new SHA); + crypto_.setCipher(new AES(AES_256_KEY_SZ)); strncpy(parms.cipher_name_, cipher_names[TLS_RSA_WITH_AES_256_CBC_SHA], MAX_SUITE_NAME); break; @@ -322,8 +298,8 @@ void SSL::set_pending(Cipher suite) parms.key_size_ = AES_128_KEY_SZ; parms.iv_size_ = AES_BLOCK_SZ; parms.cipher_type_ = block; - crypto_.setDigest(new (ys) SHA); - crypto_.setCipher(new (ys) AES); + crypto_.setDigest(new SHA); + crypto_.setCipher(new AES); strncpy(parms.cipher_name_, cipher_names[TLS_RSA_WITH_AES_128_CBC_SHA], MAX_SUITE_NAME); break; @@ -336,8 +312,8 @@ void SSL::set_pending(Cipher suite) parms.key_size_ = DES_EDE_KEY_SZ; parms.iv_size_ = DES_IV_SZ; parms.cipher_type_ = block; - crypto_.setDigest(new (ys) SHA); - crypto_.setCipher(new (ys) DES_EDE); + crypto_.setDigest(new SHA); + crypto_.setCipher(new DES_EDE); strncpy(parms.cipher_name_, cipher_names[SSL_RSA_WITH_3DES_EDE_CBC_SHA] , MAX_SUITE_NAME); break; @@ -350,8 +326,8 @@ void SSL::set_pending(Cipher suite) parms.key_size_ = DES_KEY_SZ; parms.iv_size_ = DES_IV_SZ; parms.cipher_type_ = block; - crypto_.setDigest(new (ys) SHA); - crypto_.setCipher(new (ys) DES); + crypto_.setDigest(new SHA); + crypto_.setCipher(new DES); strncpy(parms.cipher_name_, cipher_names[SSL_RSA_WITH_DES_CBC_SHA], MAX_SUITE_NAME); break; @@ -364,8 +340,8 @@ void SSL::set_pending(Cipher suite) parms.key_size_ = RC4_KEY_SZ; parms.iv_size_ = 0; parms.cipher_type_ = stream; - crypto_.setDigest(new (ys) SHA); - crypto_.setCipher(new (ys) RC4); + crypto_.setDigest(new SHA); + crypto_.setCipher(new RC4); strncpy(parms.cipher_name_, cipher_names[SSL_RSA_WITH_RC4_128_SHA], MAX_SUITE_NAME); break; @@ -378,8 +354,8 @@ void SSL::set_pending(Cipher suite) parms.key_size_ = RC4_KEY_SZ; parms.iv_size_ = 0; parms.cipher_type_ = stream; - crypto_.setDigest(new (ys) MD5); - crypto_.setCipher(new (ys) RC4); + crypto_.setDigest(new MD5); + crypto_.setCipher(new RC4); strncpy(parms.cipher_name_, cipher_names[SSL_RSA_WITH_RC4_128_MD5], MAX_SUITE_NAME); break; @@ -394,8 +370,8 @@ void SSL::set_pending(Cipher suite) parms.iv_size_ = DES_IV_SZ; parms.cipher_type_ = block; secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(new (ys) SHA); - crypto_.setCipher(new (ys) DES); + crypto_.setDigest(new SHA); + crypto_.setCipher(new DES); strncpy(parms.cipher_name_, cipher_names[SSL_DHE_RSA_WITH_DES_CBC_SHA], MAX_SUITE_NAME); break; @@ -410,8 +386,8 @@ void SSL::set_pending(Cipher suite) parms.iv_size_ = DES_IV_SZ; parms.cipher_type_ = block; secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(new (ys) SHA); - crypto_.setCipher(new (ys) DES_EDE); + crypto_.setDigest(new SHA); + crypto_.setCipher(new DES_EDE); strncpy(parms.cipher_name_, cipher_names[SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA], MAX_SUITE_NAME); break; @@ -426,8 +402,8 @@ void SSL::set_pending(Cipher suite) parms.iv_size_ = AES_BLOCK_SZ; parms.cipher_type_ = block; secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(new (ys) SHA); - crypto_.setCipher(new (ys) AES(AES_256_KEY_SZ)); + crypto_.setDigest(new SHA); + crypto_.setCipher(new AES(AES_256_KEY_SZ)); strncpy(parms.cipher_name_, cipher_names[TLS_DHE_RSA_WITH_AES_256_CBC_SHA], MAX_SUITE_NAME); break; @@ -442,8 +418,8 @@ void SSL::set_pending(Cipher suite) parms.iv_size_ = AES_BLOCK_SZ; parms.cipher_type_ = block; secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(new (ys) SHA); - crypto_.setCipher(new (ys) AES); + crypto_.setDigest(new SHA); + crypto_.setCipher(new AES); strncpy(parms.cipher_name_, cipher_names[TLS_DHE_RSA_WITH_AES_128_CBC_SHA], MAX_SUITE_NAME); break; @@ -458,8 +434,8 @@ void SSL::set_pending(Cipher suite) parms.iv_size_ = DES_IV_SZ; parms.cipher_type_ = block; secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(new (ys) SHA); - crypto_.setCipher(new (ys) DES); + crypto_.setDigest(new SHA); + crypto_.setCipher(new DES); strncpy(parms.cipher_name_, cipher_names[SSL_DHE_DSS_WITH_DES_CBC_SHA], MAX_SUITE_NAME); break; @@ -474,8 +450,8 @@ void SSL::set_pending(Cipher suite) parms.iv_size_ = DES_IV_SZ; parms.cipher_type_ = block; secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(new (ys) SHA); - crypto_.setCipher(new (ys) DES_EDE); + crypto_.setDigest(new SHA); + crypto_.setCipher(new DES_EDE); strncpy(parms.cipher_name_, cipher_names[SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA], MAX_SUITE_NAME); break; @@ -490,8 +466,8 @@ void SSL::set_pending(Cipher suite) parms.iv_size_ = AES_BLOCK_SZ; parms.cipher_type_ = block; secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(new (ys) SHA); - crypto_.setCipher(new (ys) AES(AES_256_KEY_SZ)); + crypto_.setDigest(new SHA); + crypto_.setCipher(new AES(AES_256_KEY_SZ)); strncpy(parms.cipher_name_, cipher_names[TLS_DHE_DSS_WITH_AES_256_CBC_SHA], MAX_SUITE_NAME); break; @@ -506,8 +482,8 @@ void SSL::set_pending(Cipher suite) parms.iv_size_ = AES_BLOCK_SZ; parms.cipher_type_ = block; secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(new (ys) SHA); - crypto_.setCipher(new (ys) AES); + crypto_.setDigest(new SHA); + crypto_.setCipher(new AES); strncpy(parms.cipher_name_, cipher_names[TLS_DHE_DSS_WITH_AES_128_CBC_SHA], MAX_SUITE_NAME); break; @@ -520,8 +496,8 @@ void SSL::set_pending(Cipher suite) parms.key_size_ = AES_256_KEY_SZ; parms.iv_size_ = AES_BLOCK_SZ; parms.cipher_type_ = block; - crypto_.setDigest(new (ys) RMD); - crypto_.setCipher(new (ys) AES(AES_256_KEY_SZ)); + crypto_.setDigest(new RMD); + crypto_.setCipher(new AES(AES_256_KEY_SZ)); strncpy(parms.cipher_name_, cipher_names[TLS_RSA_WITH_AES_256_CBC_RMD160], MAX_SUITE_NAME); break; @@ -534,8 +510,8 @@ void SSL::set_pending(Cipher suite) parms.key_size_ = AES_128_KEY_SZ; parms.iv_size_ = AES_BLOCK_SZ; parms.cipher_type_ = block; - crypto_.setDigest(new (ys) RMD); - crypto_.setCipher(new (ys) AES); + crypto_.setDigest(new RMD); + crypto_.setCipher(new AES); strncpy(parms.cipher_name_, cipher_names[TLS_RSA_WITH_AES_128_CBC_RMD160], MAX_SUITE_NAME); break; @@ -548,8 +524,8 @@ void SSL::set_pending(Cipher suite) parms.key_size_ = DES_EDE_KEY_SZ; parms.iv_size_ = DES_IV_SZ; parms.cipher_type_ = block; - crypto_.setDigest(new (ys) RMD); - crypto_.setCipher(new (ys) DES_EDE); + crypto_.setDigest(new RMD); + crypto_.setCipher(new DES_EDE); strncpy(parms.cipher_name_, cipher_names[TLS_RSA_WITH_3DES_EDE_CBC_RMD160], MAX_SUITE_NAME); break; @@ -564,8 +540,8 @@ void SSL::set_pending(Cipher suite) parms.iv_size_ = DES_IV_SZ; parms.cipher_type_ = block; secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(new (ys) RMD); - crypto_.setCipher(new (ys) DES_EDE); + crypto_.setDigest(new RMD); + crypto_.setCipher(new DES_EDE); strncpy(parms.cipher_name_, cipher_names[TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD160], MAX_SUITE_NAME); @@ -581,8 +557,8 @@ void SSL::set_pending(Cipher suite) parms.iv_size_ = AES_BLOCK_SZ; parms.cipher_type_ = block; secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(new (ys) RMD); - crypto_.setCipher(new (ys) AES(AES_256_KEY_SZ)); + crypto_.setDigest(new RMD); + crypto_.setCipher(new AES(AES_256_KEY_SZ)); strncpy(parms.cipher_name_, cipher_names[TLS_DHE_RSA_WITH_AES_256_CBC_RMD160], MAX_SUITE_NAME); @@ -598,8 +574,8 @@ void SSL::set_pending(Cipher suite) parms.iv_size_ = AES_BLOCK_SZ; parms.cipher_type_ = block; secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(new (ys) RMD); - crypto_.setCipher(new (ys) AES); + crypto_.setDigest(new RMD); + crypto_.setCipher(new AES); strncpy(parms.cipher_name_, cipher_names[TLS_DHE_RSA_WITH_AES_128_CBC_RMD160], MAX_SUITE_NAME); @@ -615,8 +591,8 @@ void SSL::set_pending(Cipher suite) parms.iv_size_ = DES_IV_SZ; parms.cipher_type_ = block; secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(new (ys) RMD); - crypto_.setCipher(new (ys) DES_EDE); + crypto_.setDigest(new RMD); + crypto_.setCipher(new DES_EDE); strncpy(parms.cipher_name_, cipher_names[TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD160], MAX_SUITE_NAME); @@ -632,8 +608,8 @@ void SSL::set_pending(Cipher suite) parms.iv_size_ = AES_BLOCK_SZ; parms.cipher_type_ = block; secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(new (ys) RMD); - crypto_.setCipher(new (ys) AES(AES_256_KEY_SZ)); + crypto_.setDigest(new RMD); + crypto_.setCipher(new AES(AES_256_KEY_SZ)); strncpy(parms.cipher_name_, cipher_names[TLS_DHE_DSS_WITH_AES_256_CBC_RMD160], MAX_SUITE_NAME); @@ -649,8 +625,8 @@ void SSL::set_pending(Cipher suite) parms.iv_size_ = AES_BLOCK_SZ; parms.cipher_type_ = block; secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(new (ys) RMD); - crypto_.setCipher(new (ys) AES); + crypto_.setDigest(new RMD); + crypto_.setCipher(new AES); strncpy(parms.cipher_name_, cipher_names[TLS_DHE_DSS_WITH_AES_128_CBC_RMD160], MAX_SUITE_NAME); @@ -936,12 +912,14 @@ struct SumBuffer { } // namespace for locals using namespace yassl_int_cpp_local1; + uint SSL::bufferedData() { return mySTL::for_each(buffers_.getData().begin(),buffers_.getData().end(), SumData()).total_; } + // use input buffer to fill data void SSL::fillData(Data& data) { @@ -1367,7 +1345,7 @@ typedef Mutex::Lock Lock; void Sessions::add(const SSL& ssl) { Lock guard(mutex_); - list_.push_back(new (ys) SSL_SESSION(ssl, random_)); + list_.push_back(new SSL_SESSION(ssl, random_)); } @@ -1397,6 +1375,7 @@ struct sess_match { } // local namespace using namespace yassl_int_cpp_local2; + // lookup session by id, return a copy if space provided SSL_SESSION* Sessions::lookup(const opaque* id, SSL_SESSION* copy) { @@ -1764,7 +1743,7 @@ void Crypto::SetDH(DiffieHellman* dh) void Crypto::SetDH(const DH_Parms& dh) { if (dh.set_) - dh_ = new (ys) DiffieHellman(dh.p_, dh.g_, random_); + dh_ = new DiffieHellman(dh.p_, dh.g_, random_); } @@ -1931,7 +1910,7 @@ X509_NAME::X509_NAME(const char* n, size_t sz) : name_(0) { if (sz) { - name_ = new (ys) char[sz]; + name_ = new char[sz]; memcpy(name_, n, sz); } } @@ -1952,7 +1931,7 @@ char* X509_NAME::GetName() X509::X509(const char* i, size_t iSz, const char* s, size_t sSz) : issuer_(i, iSz), subject_(s, sSz) {} - + X509_NAME* X509::GetIssuer() { diff --git a/extra/yassl/taocrypt/include/aes.hpp b/extra/yassl/taocrypt/include/aes.hpp index b2c93eff9fe..b8436d35c5f 100644 --- a/extra/yassl/taocrypt/include/aes.hpp +++ b/extra/yassl/taocrypt/include/aes.hpp @@ -37,11 +37,12 @@ enum { AES_BLOCK_SIZE = 16 }; // AES encryption and decryption, see FIPS-197 -class AES : public Mode_BASE { +class AES : public Mode_BASE { public: enum { BLOCK_SIZE = AES_BLOCK_SIZE }; - AES(CipherDir DIR, Mode MODE) : dir_(DIR), mode_(MODE) {} + AES(CipherDir DIR, Mode MODE) + : Mode_BASE(BLOCK_SIZE), dir_(DIR), mode_(MODE) {} void Process(byte*, const byte*, word32); void SetKey(const byte* iv, word32 sz, CipherDir fake = ENCRYPTION); diff --git a/extra/yassl/taocrypt/include/algebra.hpp b/extra/yassl/taocrypt/include/algebra.hpp index 74f244507f6..92cac607d97 100644 --- a/extra/yassl/taocrypt/include/algebra.hpp +++ b/extra/yassl/taocrypt/include/algebra.hpp @@ -24,11 +24,10 @@ #ifndef TAO_CRYPT_ALGEBRA_HPP #define TAO_CRYPT_ALGEBRA_HPP -#include "misc.hpp" +#include "integer.hpp" namespace TaoCrypt { -class Integer; // "const Element&" returned by member functions are references // to internal data members. Since each object may have only @@ -38,11 +37,11 @@ class Integer; // But this should be fine: // abcd = group.Add(a, group.Add(b, group.Add(c,d)); -//! Abstract Group -template class TAOCRYPT_NO_VTABLE AbstractGroup +// Abstract Group +class TAOCRYPT_NO_VTABLE AbstractGroup { public: - typedef T Element; + typedef Integer Element; virtual ~AbstractGroup() {} @@ -65,15 +64,14 @@ public: const Integer *exponents, unsigned int exponentsCount) const; }; -//! Abstract Ring -template class TAOCRYPT_NO_VTABLE AbstractRing - : public AbstractGroup +// Abstract Ring +class TAOCRYPT_NO_VTABLE AbstractRing : public AbstractGroup { public: - typedef T Element; + typedef Integer Element; AbstractRing() {m_mg.m_pRing = this;} - AbstractRing(const AbstractRing &source) {m_mg.m_pRing = this;} + AbstractRing(const AbstractRing &source) : AbstractGroup() {m_mg.m_pRing = this;} AbstractRing& operator=(const AbstractRing &source) {return *this;} virtual bool IsUnit(const Element &a) const =0; @@ -91,14 +89,14 @@ public: virtual void SimultaneousExponentiate(Element *results, const Element&, const Integer *exponents, unsigned int exponentsCount) const; - virtual const AbstractGroup& MultiplicativeGroup() const + virtual const AbstractGroup& MultiplicativeGroup() const {return m_mg;} private: - class MultiplicativeGroupT : public AbstractGroup + class MultiplicativeGroupT : public AbstractGroup { public: - const AbstractRing& GetRing() const + const AbstractRing& GetRing() const {return *m_pRing;} bool Equal(const Element &a, const Element &b) const @@ -137,44 +135,19 @@ private: {GetRing().SimultaneousExponentiate(results, base, exponents, exponentsCount);} - const AbstractRing *m_pRing; + const AbstractRing* m_pRing; }; MultiplicativeGroupT m_mg; }; -// ******************************************************** -//! Base and Exponent -template -struct BaseAndExponent +// Abstract Euclidean Domain +class TAOCRYPT_NO_VTABLE AbstractEuclideanDomain + : public AbstractRing { public: - BaseAndExponent() {} - BaseAndExponent(const T &base, const E &exponent) : base(base), - exponent(exponent) {} - bool operator<(const BaseAndExponent &rhs) const - {return exponent < rhs.exponent;} - T base; - E exponent; -}; - -// VC60 workaround: incomplete member template support -template - Element GeneralCascadeMultiplication(const AbstractGroup &group, - Iterator begin, Iterator end); -template - Element GeneralCascadeExponentiation(const AbstractRing &ring, - Iterator begin, Iterator end); - -// ******************************************************** - -//! Abstract Euclidean Domain -template class TAOCRYPT_NO_VTABLE AbstractEuclideanDomain - : public AbstractRing -{ -public: - typedef T Element; + typedef Integer Element; virtual void DivisionAlgorithm(Element &r, Element &q, const Element &a, const Element &d) const =0; @@ -186,13 +159,12 @@ protected: mutable Element result; }; -// ******************************************************** -//! EuclideanDomainOf -template class EuclideanDomainOf : public AbstractEuclideanDomain +// EuclideanDomainOf +class EuclideanDomainOf : public AbstractEuclideanDomain { public: - typedef T Element; + typedef Integer Element; EuclideanDomainOf() {} @@ -249,68 +221,8 @@ private: mutable Element result; }; -//! Quotient Ring -template class QuotientRing : public AbstractRing -{ -public: - typedef T EuclideanDomain; - typedef typename T::Element Element; - - QuotientRing(const EuclideanDomain &domain, const Element &modulus) - : m_domain(domain), m_modulus(modulus) {} - - const EuclideanDomain & GetDomain() const - {return m_domain;} - - const Element& GetModulus() const - {return m_modulus;} - - bool Equal(const Element &a, const Element &b) const - {return m_domain.Equal(m_domain.Mod(m_domain.Subtract(a, b), - m_modulus), m_domain.Identity());} - - const Element& Identity() const - {return m_domain.Identity();} - - const Element& Add(const Element &a, const Element &b) const - {return m_domain.Add(a, b);} - - Element& Accumulate(Element &a, const Element &b) const - {return m_domain.Accumulate(a, b);} - - const Element& Inverse(const Element &a) const - {return m_domain.Inverse(a);} - - const Element& Subtract(const Element &a, const Element &b) const - {return m_domain.Subtract(a, b);} - - Element& Reduce(Element &a, const Element &b) const - {return m_domain.Reduce(a, b);} - - const Element& Double(const Element &a) const - {return m_domain.Double(a);} - - bool IsUnit(const Element &a) const - {return m_domain.IsUnit(m_domain.Gcd(a, m_modulus));} - - const Element& MultiplicativeIdentity() const - {return m_domain.MultiplicativeIdentity();} - - const Element& Multiply(const Element &a, const Element &b) const - {return m_domain.Mod(m_domain.Multiply(a, b), m_modulus);} - - const Element& Square(const Element &a) const - {return m_domain.Mod(m_domain.Square(a), m_modulus);} - - const Element& MultiplicativeInverse(const Element &a) const; - -protected: - EuclideanDomain m_domain; - Element m_modulus; -}; } // namespace - #endif // TAO_CRYPT_ALGEBRA_HPP diff --git a/extra/yassl/taocrypt/include/block.hpp b/extra/yassl/taocrypt/include/block.hpp index f490fb0b6e7..f3c4415682d 100644 --- a/extra/yassl/taocrypt/include/block.hpp +++ b/extra/yassl/taocrypt/include/block.hpp @@ -34,10 +34,6 @@ #include // ptrdiff_t -#if defined(_MSC_VER) && defined(_CRTAPI1) -#define TAOCRYPT_MSVCRT6 -#endif - namespace TaoCrypt { @@ -47,13 +43,13 @@ template class AllocatorBase { public: - typedef T value_type; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; + typedef T value_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef T& reference; + typedef const T& const_reference; pointer address(reference r) const {return (&r);} const_pointer address(const_reference r) const {return (&r); } @@ -104,7 +100,7 @@ public: CheckSize(n); if (n == 0) return 0; - return new (tc) T[n]; + return new T[n]; } void deallocate(void* p, size_type n) diff --git a/extra/yassl/taocrypt/include/des.hpp b/extra/yassl/taocrypt/include/des.hpp index e8100b4e198..127b8ddc6d5 100644 --- a/extra/yassl/taocrypt/include/des.hpp +++ b/extra/yassl/taocrypt/include/des.hpp @@ -36,12 +36,13 @@ namespace TaoCrypt { enum { DES_BLOCK_SIZE = 8 }; // Base for all DES types -class DES_BASE : public Mode_BASE { +class DES_BASE : public Mode_BASE { public: enum { BLOCK_SIZE = DES_BLOCK_SIZE, KEY_SIZE = 32, BOXES = 8, BOX_SIZE = 64 }; - DES_BASE(CipherDir DIR, Mode MODE) : dir_(DIR), mode_(MODE) {} + DES_BASE(CipherDir DIR, Mode MODE) + : Mode_BASE(BLOCK_SIZE), dir_(DIR), mode_(MODE) {} void Process(byte*, const byte*, word32); protected: diff --git a/extra/yassl/taocrypt/include/error.hpp b/extra/yassl/taocrypt/include/error.hpp index 6170d0349b5..55ab39313f5 100644 --- a/extra/yassl/taocrypt/include/error.hpp +++ b/extra/yassl/taocrypt/include/error.hpp @@ -65,7 +65,8 @@ UNKOWN_HASH_E = 1034, // "unknown hash OID" DSA_SZ_E = 1035, // "bad DSA r or s size" BEFORE_DATE_E = 1036, // "before date in the future" AFTER_DATE_E = 1037, // "after date in the past" -SIG_CONFIRM_E = 1038 // "bad signature confirmation" +SIG_CONFIRM_E = 1038, // "bad self signature confirmation" +SIG_OTHER_E = 1039 // "bad other signature confirmation" }; diff --git a/extra/yassl/taocrypt/include/hash.hpp b/extra/yassl/taocrypt/include/hash.hpp index 1703de23713..f01f343c2d1 100644 --- a/extra/yassl/taocrypt/include/hash.hpp +++ b/extra/yassl/taocrypt/include/hash.hpp @@ -50,7 +50,7 @@ public: class HASHwithTransform : public HASH { public: HASHwithTransform(word32 digSz, word32 buffSz) - : digest_(new (tc) word32[digSz]), buffer_(new (tc) byte[buffSz]) {} + : digest_(new word32[digSz]), buffer_(new byte[buffSz]) {} virtual ~HASHwithTransform() { delete[] buffer_; delete[] digest_; } virtual ByteOrder getByteOrder() const = 0; diff --git a/extra/yassl/taocrypt/include/integer.hpp b/extra/yassl/taocrypt/include/integer.hpp index 3713d09d9f9..6b1984e46ed 100644 --- a/extra/yassl/taocrypt/include/integer.hpp +++ b/extra/yassl/taocrypt/include/integer.hpp @@ -29,8 +29,8 @@ #include "block.hpp" #include "random.hpp" #include "file.hpp" -#include #include "algorithm.hpp" // mySTL::swap +#include #ifdef TAOCRYPT_X86ASM_AVAILABLE @@ -128,9 +128,6 @@ public: Integer(signed long value); Integer(Sign s, word highWord, word lowWord); - explicit Integer(const char* str); - explicit Integer(const wchar_t* str); - // BER Decode Source explicit Integer(Source&); @@ -254,15 +251,13 @@ public: private: friend class ModularArithmetic; friend class MontgomeryRepresentation; - friend class HalfMontgomeryRepresentation; - Integer(word value, unsigned int length); static const Integer zero; static const Integer one; static const Integer two; - int PositiveCompare(const Integer& t) const; + friend void PositiveAdd(Integer& sum, const Integer& a, const Integer& b); friend void PositiveSubtract(Integer& diff, const Integer& a, const Integer& b); @@ -308,6 +303,7 @@ inline void swap(Integer &a, Integer &b) Integer CRT(const Integer& xp, const Integer& p, const Integer& xq, const Integer& q, const Integer& u); + inline Integer ModularExponentiation(const Integer& a, const Integer& e, const Integer& m) { diff --git a/extra/yassl/taocrypt/include/misc.hpp b/extra/yassl/taocrypt/include/misc.hpp index b5b0a4575fc..de8cbb30fcb 100644 --- a/extra/yassl/taocrypt/include/misc.hpp +++ b/extra/yassl/taocrypt/include/misc.hpp @@ -28,17 +28,6 @@ #include #include -namespace TaoCrypt { - -// library allocation -struct new_t {}; // TaoCrypt New type -extern new_t tc; // pass in parameter - -} // namespace TaoCrypt - -void* operator new (size_t, TaoCrypt::new_t); -void* operator new[](size_t, TaoCrypt::new_t); - namespace TaoCrypt { diff --git a/extra/yassl/taocrypt/include/modarith.hpp b/extra/yassl/taocrypt/include/modarith.hpp index 88a2cc95c7c..66a841b05c3 100644 --- a/extra/yassl/taocrypt/include/modarith.hpp +++ b/extra/yassl/taocrypt/include/modarith.hpp @@ -27,14 +27,13 @@ #define TAO_CRYPT_MODARITH_HPP #include "misc.hpp" -#include "integer.hpp" #include "algebra.hpp" namespace TaoCrypt { -//! ModularArithmetic -class ModularArithmetic : public AbstractRing +// ModularArithmetic +class ModularArithmetic : public AbstractRing { public: @@ -45,7 +44,7 @@ public: : modulus(modulus), result((word)0, modulus.reg_.size()) {} ModularArithmetic(const ModularArithmetic &ma) - : AbstractRing(), + : AbstractRing(), modulus(ma.modulus), result((word)0, modulus.reg_.size()) {} const Integer& GetModulus() const {return modulus;} @@ -149,12 +148,12 @@ public: Integer CascadeExponentiate(const Integer &x, const Integer &e1, const Integer &y, const Integer &e2) const - {return AbstractRing::CascadeExponentiate(x, e1, y, e2);} + {return AbstractRing::CascadeExponentiate(x, e1, y, e2);} void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const - {AbstractRing::SimultaneousExponentiate(results, base, - exponents, exponentsCount);} + {AbstractRing::SimultaneousExponentiate(results, base, + exponents, exponentsCount);} private: Integer u; diff --git a/extra/yassl/taocrypt/include/modes.hpp b/extra/yassl/taocrypt/include/modes.hpp index 2a21ad46b76..3f9878a9e62 100644 --- a/extra/yassl/taocrypt/include/modes.hpp +++ b/extra/yassl/taocrypt/include/modes.hpp @@ -56,10 +56,11 @@ private: // Mode Base for block ciphers, static size -template class Mode_BASE { public: - Mode_BASE() {} + enum { MaxBlockSz = 16 }; + + explicit Mode_BASE(int sz) : blockSz_(sz) { assert(sz <= MaxBlockSz); } virtual ~Mode_BASE() {} virtual void ProcessAndXorBlock(const byte*, const byte*, byte*) const = 0; @@ -68,10 +69,11 @@ public: void CBC_Encrypt(byte*, const byte*, word32); void CBC_Decrypt(byte*, const byte*, word32); - void SetIV(const byte* iv) { memcpy(reg_, iv, BLOCK_SIZE); } + void SetIV(const byte* iv) { memcpy(reg_, iv, blockSz_); } private: - byte reg_[BLOCK_SIZE]; - byte tmp_[BLOCK_SIZE]; + byte reg_[MaxBlockSz]; + byte tmp_[MaxBlockSz]; + int blockSz_; Mode_BASE(const Mode_BASE&); // hide copy Mode_BASE& operator=(const Mode_BASE&); // and assign @@ -79,51 +81,48 @@ private: // ECB Process blocks -template -void Mode_BASE::ECB_Process(byte* out, const byte* in, word32 sz) +inline void Mode_BASE::ECB_Process(byte* out, const byte* in, word32 sz) { - word32 blocks = sz / BLOCK_SIZE; + word32 blocks = sz / blockSz_; while (blocks--) { ProcessAndXorBlock(in, 0, out); - out += BLOCK_SIZE; - in += BLOCK_SIZE; + out += blockSz_; + in += blockSz_; } } // CBC Encrypt -template -void Mode_BASE::CBC_Encrypt(byte* out, const byte* in, word32 sz) +inline void Mode_BASE::CBC_Encrypt(byte* out, const byte* in, word32 sz) { - word32 blocks = sz / BLOCK_SIZE; + word32 blocks = sz / blockSz_; while (blocks--) { - xorbuf(reg_, in, BLOCK_SIZE); + xorbuf(reg_, in, blockSz_); ProcessAndXorBlock(reg_, 0, reg_); - memcpy(out, reg_, BLOCK_SIZE); - out += BLOCK_SIZE; - in += BLOCK_SIZE; + memcpy(out, reg_, blockSz_); + out += blockSz_; + in += blockSz_; } } // CBC Decrypt -template -void Mode_BASE::CBC_Decrypt(byte* out, const byte* in, word32 sz) +inline void Mode_BASE::CBC_Decrypt(byte* out, const byte* in, word32 sz) { - word32 blocks = sz / BLOCK_SIZE; - byte hold[BLOCK_SIZE]; + word32 blocks = sz / blockSz_; + byte hold[MaxBlockSz]; while (blocks--) { - memcpy(tmp_, in, BLOCK_SIZE); + memcpy(tmp_, in, blockSz_); ProcessAndXorBlock(tmp_, 0, out); - xorbuf(out, reg_, BLOCK_SIZE); - memcpy(hold, reg_, BLOCK_SIZE); // swap reg_ and tmp_ - memcpy(reg_, tmp_, BLOCK_SIZE); - memcpy(tmp_, hold, BLOCK_SIZE); - out += BLOCK_SIZE; - in += BLOCK_SIZE; + xorbuf(out, reg_, blockSz_); + memcpy(hold, reg_, blockSz_); // swap reg_ and tmp_ + memcpy(reg_, tmp_, blockSz_); + memcpy(tmp_, hold, blockSz_); + out += blockSz_; + in += blockSz_; } } diff --git a/extra/yassl/taocrypt/src/algebra.cpp b/extra/yassl/taocrypt/src/algebra.cpp index 1924be9b618..d70f8dd5d72 100644 --- a/extra/yassl/taocrypt/src/algebra.cpp +++ b/extra/yassl/taocrypt/src/algebra.cpp @@ -23,60 +23,58 @@ #include "runtime.hpp" #include "algebra.hpp" -#include "integer.hpp" #include "vector.hpp" // mySTL::vector (simple) namespace TaoCrypt { -template const T& AbstractGroup::Double(const Element &a) const + +const Integer& AbstractGroup::Double(const Element &a) const { return Add(a, a); } -template const T& AbstractGroup::Subtract(const Element &a, - const Element &b) const +const Integer& AbstractGroup::Subtract(const Element &a, const Element &b) const { // make copy of a in case Inverse() overwrites it Element a1(a); return Add(a1, Inverse(b)); } -template T& AbstractGroup::Accumulate(Element &a, - const Element &b) const +Integer& AbstractGroup::Accumulate(Element &a, const Element &b) const { return a = Add(a, b); } -template T& AbstractGroup::Reduce(Element &a, - const Element &b) const +Integer& AbstractGroup::Reduce(Element &a, const Element &b) const { return a = Subtract(a, b); } -template const T& AbstractRing::Square(const Element &a) const +const Integer& AbstractRing::Square(const Element &a) const { return Multiply(a, a); } -template const T& AbstractRing::Divide(const Element &a, - const Element &b) const + +const Integer& AbstractRing::Divide(const Element &a, const Element &b) const { // make copy of a in case MultiplicativeInverse() overwrites it Element a1(a); return Multiply(a1, MultiplicativeInverse(b)); } -template const T& AbstractEuclideanDomain::Mod(const Element &a, - const Element &b) const + +const Integer& AbstractEuclideanDomain::Mod(const Element &a, + const Element &b) const { Element q; DivisionAlgorithm(result, q, a, b); return result; } -template const T& AbstractEuclideanDomain::Gcd(const Element &a, - const Element &b) const +const Integer& AbstractEuclideanDomain::Gcd(const Element &a, + const Element &b) const { Element g[3]={b, a}; unsigned int i0=0, i1=1, i2=2; @@ -90,45 +88,17 @@ template const T& AbstractEuclideanDomain::Gcd(const Element &a, return result = g[i0]; } -template const typename - QuotientRing::Element& QuotientRing::MultiplicativeInverse( - const Element &a) const -{ - Element g[3]={m_modulus, a}; -#ifdef __BCPLUSPLUS__ - // BC++50 workaround - Element v[3]; - v[0]=m_domain.Identity(); - v[1]=m_domain.MultiplicativeIdentity(); -#else - Element v[3]={m_domain.Identity(), m_domain.MultiplicativeIdentity()}; -#endif - Element y; - unsigned int i0=0, i1=1, i2=2; - while (!Equal(g[i1], Identity())) - { - // y = g[i0] / g[i1]; - // g[i2] = g[i0] % g[i1]; - m_domain.DivisionAlgorithm(g[i2], y, g[i0], g[i1]); - // v[i2] = v[i0] - (v[i1] * y); - v[i2] = m_domain.Subtract(v[i0], m_domain.Multiply(v[i1], y)); - unsigned int t = i0; i0 = i1; i1 = i2; i2 = t; - } - - return m_domain.IsUnit(g[i0]) ? m_domain.Divide(v[i0], g[i0]) : - m_domain.Identity(); -} - -template T AbstractGroup::ScalarMultiply(const Element &base, - const Integer &exponent) const +Integer AbstractGroup::ScalarMultiply(const Element &base, + const Integer &exponent) const { Element result; SimultaneousMultiply(&result, base, &exponent, 1); return result; } -template T AbstractGroup::CascadeScalarMultiply(const Element &x, + +Integer AbstractGroup::CascadeScalarMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const { const unsigned expLen = max(e1.BitCount(), e2.BitCount()); @@ -258,8 +228,8 @@ struct WindowSlider bool fastNegate, negateNext, firstTime, finished; }; -template -void AbstractGroup::SimultaneousMultiply(T *results, const T &base, + +void AbstractGroup::SimultaneousMultiply(Integer *results, const Integer &base, const Integer *expBegin, unsigned int expCount) const { mySTL::vector > buckets(expCount); @@ -321,34 +291,39 @@ void AbstractGroup::SimultaneousMultiply(T *results, const T &base, } } -template T AbstractRing::Exponentiate(const Element &base, - const Integer &exponent) const +Integer AbstractRing::Exponentiate(const Element &base, + const Integer &exponent) const { Element result; SimultaneousExponentiate(&result, base, &exponent, 1); return result; } -template T AbstractRing::CascadeExponentiate(const Element &x, + +Integer AbstractRing::CascadeExponentiate(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const { - return MultiplicativeGroup().AbstractGroup::CascadeScalarMultiply( + return MultiplicativeGroup().AbstractGroup::CascadeScalarMultiply( x, e1, y, e2); } -template Element GeneralCascadeExponentiation( - const AbstractRing &ring, Iterator begin, Iterator end) -{ - return GeneralCascadeMultiplication(ring.MultiplicativeGroup(), - begin, end); -} -template -void AbstractRing::SimultaneousExponentiate(T *results, const T &base, +void AbstractRing::SimultaneousExponentiate(Integer *results, + const Integer &base, const Integer *exponents, unsigned int expCount) const { - MultiplicativeGroup().AbstractGroup::SimultaneousMultiply(results, base, + MultiplicativeGroup().AbstractGroup::SimultaneousMultiply(results, base, exponents, expCount); } + } // namespace + +#ifdef __GNUC__ +namespace mySTL { +template TaoCrypt::WindowSlider* uninit_copy(TaoCrypt::WindowSlider*, TaoCrypt::WindowSlider*, TaoCrypt::WindowSlider*); +template vector* uninit_fill_n*, unsigned int, vector >(vector*, unsigned int, vector const&); +template void destroy(TaoCrypt::WindowSlider*, TaoCrypt::WindowSlider*); +template void destroy*>(vector*, vector*); +} +#endif diff --git a/extra/yassl/taocrypt/src/asn.cpp b/extra/yassl/taocrypt/src/asn.cpp index d0d22a6c61d..59c544bd633 100644 --- a/extra/yassl/taocrypt/src/asn.cpp +++ b/extra/yassl/taocrypt/src/asn.cpp @@ -187,7 +187,7 @@ PublicKey::PublicKey(const byte* k, word32 s) : key_(0), sz_(0) void PublicKey::SetSize(word32 s) { sz_ = s; - key_ = new (tc) byte[sz_]; + key_ = new byte[sz_]; } @@ -199,7 +199,7 @@ void PublicKey::SetKey(const byte* k) void PublicKey::AddToEnd(const byte* data, word32 len) { - mySTL::auto_ptr tmp(new (tc) byte[sz_ + len]); + mySTL::auto_ptr tmp(new byte[sz_ + len]); memcpy(tmp.get(), key_, sz_); memcpy(tmp.get() + sz_, data, len); @@ -218,7 +218,7 @@ Signer::Signer(const byte* k, word32 kSz, const char* n, const byte* h) { if (n) { int sz = strlen(n); - name_ = new (tc) char[sz + 1]; + name_ = new char[sz + 1]; memcpy(name_, n, sz); name_[sz] = 0; } @@ -480,7 +480,7 @@ void CertDecoder::Decode(SignerList* signers) } else if (!ValidateSignature(signers)) - source_.SetError(SIG_CONFIRM_E); + source_.SetError(SIG_OTHER_E); } @@ -632,7 +632,7 @@ word32 CertDecoder::GetSignature() } sigLength_--; - signature_ = new (tc) byte[sigLength_]; + signature_ = new byte[sigLength_]; memcpy(signature_, source_.get_current(), sigLength_); source_.advance(sigLength_); @@ -653,7 +653,7 @@ word32 CertDecoder::GetDigest() sigLength_ = GetLength(source_); - signature_ = new (tc) byte[sigLength_]; + signature_ = new byte[sigLength_]; memcpy(signature_, source_.get_current(), sigLength_); source_.advance(sigLength_); @@ -693,7 +693,7 @@ void CertDecoder::GetName(NameType nt) if (id == COMMON_NAME) { char*& ptr = (nt == ISSUER) ? issuer_ : subject_; - ptr = new (tc) char[strLen + 1]; + ptr = new char[strLen + 1]; memcpy(ptr, source_.get_current(), strLen); ptr[strLen] = 0; } @@ -810,15 +810,15 @@ bool CertDecoder::ConfirmSignature(Source& pub) mySTL::auto_ptr hasher; if (signatureOID_ == MD5wRSA) { - hasher.reset(new (tc) MD5); + hasher.reset(new MD5); ht = MD5h; } else if (signatureOID_ == MD2wRSA) { - hasher.reset(new (tc) MD2); + hasher.reset(new MD2); ht = MD2h; } else if (signatureOID_ == SHAwRSA || signatureOID_ == SHAwDSA) { - hasher.reset(new (tc) SHA); + hasher.reset(new SHA); ht = SHAh; } else { diff --git a/extra/yassl/taocrypt/src/dh.cpp b/extra/yassl/taocrypt/src/dh.cpp index af50d471b52..ea1b5846f7d 100644 --- a/extra/yassl/taocrypt/src/dh.cpp +++ b/extra/yassl/taocrypt/src/dh.cpp @@ -26,7 +26,6 @@ #include "runtime.hpp" #include "dh.hpp" #include "asn.hpp" -#include namespace TaoCrypt { diff --git a/extra/yassl/taocrypt/src/dsa.cpp b/extra/yassl/taocrypt/src/dsa.cpp index 4716ebb22df..5cb3018a402 100644 --- a/extra/yassl/taocrypt/src/dsa.cpp +++ b/extra/yassl/taocrypt/src/dsa.cpp @@ -27,8 +27,6 @@ #include "modarith.hpp" #include "stdexcept.hpp" -#include "algebra.cpp" // for GCC 3.2 on aix ? - namespace TaoCrypt { diff --git a/extra/yassl/taocrypt/src/integer.cpp b/extra/yassl/taocrypt/src/integer.cpp index 9be0a25b363..37cfe374451 100644 --- a/extra/yassl/taocrypt/src/integer.cpp +++ b/extra/yassl/taocrypt/src/integer.cpp @@ -38,11 +38,10 @@ #include "asn.hpp" #include "stdexcept.hpp" -#include "algebra.cpp" #ifdef __DECCXX - #include // for asm multiply overflow + #include // for asm overflow assembly #endif @@ -63,7 +62,7 @@ #pragma message("You do not seem to have the Visual C++ Processor Pack ") #pragma message("installed, so use of SSE2 intrinsics will be disabled.") #elif defined(__GNUC__) && defined(__i386__) -/* #warning You do not have GCC 3.3 or later, or did not specify the -msse2 \ +/* #warning You do not have GCC 3.3 or later, or did not specify the -msse2 \ compiler option. Use of SSE2 intrinsics will be disabled. */ #endif @@ -109,7 +108,7 @@ CPP_TYPENAME AllocatorBase::pointer AlignedAllocator::allocate( assert(IsAlignedOn(p, 16)); return (T*)p; } - return new (tc) T[n]; + return new T[n]; } @@ -178,7 +177,7 @@ DWord() {} #elif defined(__DECCXX) r.halfs_.high = asm("umulh %a0, %a1, %v0", a, b); #else - #error unsupported alpha compiler for asm multiply overflow + #error can not implement multiply overflow #endif #elif defined(__ia64__) r.halfs_.low = a*b; @@ -392,6 +391,7 @@ S DivideThreeWordsByTwo(S* A, S B0, S B1, D* dummy_VC6_WorkAround = 0) return Q; } + // do a 4 word by 2 word divide, returns 2 word quotient in Q0 and Q1 template inline D DivideFourWordsByTwo(S *T, const D &Al, const D &Ah, const D &B) @@ -470,66 +470,6 @@ static inline unsigned int RoundupSize(unsigned int n) } -template -static Integer StringToInteger(const T *str) -{ - word radix; - - unsigned int length; - for (length = 0; str[length] != 0; length++) {} - - Integer v; - - if (length == 0) - return v; - - switch (str[length-1]) - { - case 'h': - case 'H': - radix=16; - break; - case 'o': - case 'O': - radix=8; - break; - case 'b': - case 'B': - radix=2; - break; - default: - radix=10; - } - - if (length > 2 && str[0] == '0' && str[1] == 'x') - radix = 16; - - for (unsigned i=0; i= '0' && str[i] <= '9') - digit = str[i] - '0'; - else if (str[i] >= 'A' && str[i] <= 'F') - digit = str[i] - 'A' + 10; - else if (str[i] >= 'a' && str[i] <= 'f') - digit = str[i] - 'a' + 10; - else - digit = radix; - - if (digit < radix) - { - v *= radix; - v += digit; - } - } - - if (str[0] == '-') - v.Negate(); - - return v; -} - static int Compare(const word *A, const word *B, unsigned int N) { while (N--) @@ -2308,85 +2248,6 @@ void RecursiveMultiplyBottom(word *R, word *T, const word *A, const word *B, } } -/* -template -void RecursiveMultiplyTop(word *R, word *T, const word *L, const word *A, - const word *B, unsigned int N, const P *dummy=0) -{ - assert(N>=2 && N%2==0); - - if (N==4) - { - P::Multiply4(T, A, B); - ((dword *)R)[0] = ((dword *)T)[2]; - ((dword *)R)[1] = ((dword *)T)[3]; - } - else if (N==2) - { - P::Multiply2(T, A, B); - ((dword *)R)[0] = ((dword *)T)[1]; - } - else - { - const unsigned int N2 = N/2; - int carry; - - int aComp = Compare(A0, A1, N2); - int bComp = Compare(B0, B1, N2); - - switch (2*aComp + aComp + bComp) - { - case -4: - P::Subtract(R0, A1, A0, N2); - P::Subtract(R1, B0, B1, N2); - RecursiveMultiply

(T0, T2, R0, R1, N2); - P::Subtract(T1, T1, R0, N2); - carry = -1; - break; - case -2: - P::Subtract(R0, A1, A0, N2); - P::Subtract(R1, B0, B1, N2); - RecursiveMultiply

(T0, T2, R0, R1, N2); - carry = 0; - break; - case 2: - P::Subtract(R0, A0, A1, N2); - P::Subtract(R1, B1, B0, N2); - RecursiveMultiply

(T0, T2, R0, R1, N2); - carry = 0; - break; - case 4: - P::Subtract(R0, A1, A0, N2); - P::Subtract(R1, B0, B1, N2); - RecursiveMultiply

(T0, T2, R0, R1, N2); - P::Subtract(T1, T1, R1, N2); - carry = -1; - break; - default: - SetWords(T0, 0, N); - carry = 0; - } - - RecursiveMultiply

(T2, R0, A1, B1, N2); - - // now T[01] holds (A1-A0)*(B0-B1), T[23] holds A1*B1 - - word c2 = P::Subtract(R0, L+N2, L, N2); - c2 += P::Subtract(R0, R0, T0, N2); - word t = (Compare(R0, T2, N2) == -1); - - carry += t; - carry += Increment(R0, N2, c2+t); - carry += P::Add(R0, R0, T1, N2); - carry += P::Add(R0, R0, T3, N2); - assert (carry >= 0 && carry <= 2); - - CopyWords(R1, T3, N2); - Increment(R1, N2, carry); - } -} -*/ - void RecursiveMultiplyTop(word *R, word *T, const word *L, const word *A, const word *B, unsigned int N) @@ -2739,20 +2600,6 @@ Integer::Integer(word value, unsigned int length) } -Integer::Integer(const char *str) - : reg_(2), sign_(POSITIVE) -{ - *this = StringToInteger(str); -} - - -Integer::Integer(const wchar_t *str) - : reg_(2), sign_(POSITIVE) -{ - *this = StringToInteger(str); -} - - Integer::Integer(const byte *encodedInteger, unsigned int byteCount, Signedness s) { @@ -3358,76 +3205,6 @@ Integer Integer::Times(const Integer &b) const #undef R2 #undef R3 -/* -// do a 3 word by 2 word divide, returns quotient and leaves remainder in A -static word SubatomicDivide(word *A, word B0, word B1) -{ - // assert {A[2],A[1]} < {B1,B0}, so quotient can fit in a word - assert(A[2] < B1 || (A[2]==B1 && A[1] < B0)); - - dword p, u; - word Q; - - // estimate the quotient: do a 2 word by 1 word divide - if (B1+1 == 0) - Q = A[2]; - else - Q = word(MAKE_DWORD(A[1], A[2]) / (B1+1)); - - // now subtract Q*B from A - p = (dword) B0*Q; - u = (dword) A[0] - LOW_WORD(p); - A[0] = LOW_WORD(u); - u = (dword) A[1] - HIGH_WORD(p) - (word)(0-HIGH_WORD(u)) - (dword)B1*Q; - A[1] = LOW_WORD(u); - A[2] += HIGH_WORD(u); - - // Q <= actual quotient, so fix it - while (A[2] || A[1] > B1 || (A[1]==B1 && A[0]>=B0)) - { - u = (dword) A[0] - B0; - A[0] = LOW_WORD(u); - u = (dword) A[1] - B1 - (word)(0-HIGH_WORD(u)); - A[1] = LOW_WORD(u); - A[2] += HIGH_WORD(u); - Q++; - assert(Q); // shouldn't overflow - } - - return Q; -} -*/ - - -/* -// do a 4 word by 2 word divide, returns 2 word quotient in Q0 and Q1 -static inline void AtomicDivide(word *Q, const word *A, const word *B) -{ - if (!B[0] && !B[1]) // if divisor is 0, we assume divisor==2**(2*WORD_BITS) - { - Q[0] = A[2]; - Q[1] = A[3]; - } - else - { - word T[4]; - T[0] = A[0]; T[1] = A[1]; T[2] = A[2]; T[3] = A[3]; - Q[1] = SubatomicDivide(T+1, B[0], B[1]); - Q[0] = SubatomicDivide(T, B[0], B[1]); - -#ifndef NDEBUG - // multiply quotient and divisor and add remainder - // make sure it equals dividend - assert(!T[2] && !T[3] && (T[1] < B[1] || (T[1]==B[1] && T[0]().Gcd(a, b); + return EuclideanDomainOf().Gcd(a, b); } Integer Integer::InverseMod(const Integer &m) const @@ -3955,7 +3732,7 @@ Integer ModularArithmetic::CascadeExponentiate(const Integer &x, dr.ConvertIn(y), e2)); } else - return AbstractRing::CascadeExponentiate(x, e1, y, e2); + return AbstractRing::CascadeExponentiate(x, e1, y, e2); } void ModularArithmetic::SimultaneousExponentiate(Integer *results, @@ -3971,7 +3748,7 @@ void ModularArithmetic::SimultaneousExponentiate(Integer *results, results[i] = dr.ConvertOut(results[i]); } else - AbstractRing::SimultaneousExponentiate(results, base, + AbstractRing::SimultaneousExponentiate(results, base, exponents, exponentsCount); } @@ -4170,10 +3947,6 @@ Integer CRT(const Integer &xp, const Integer &p, const Integer &xq, } #ifdef __GNUC__ -template Integer StringToInteger(char const*); -template Integer StringToInteger(wchar_t const*); -template class EuclideanDomainOf; -template class AbstractEuclideanDomain; template unsigned int DivideThreeWordsByTwo(unsigned int*, unsigned int, unsigned int, DWord*); #endif diff --git a/extra/yassl/taocrypt/src/misc.cpp b/extra/yassl/taocrypt/src/misc.cpp index e4573abac3f..37d1bd1b14d 100644 --- a/extra/yassl/taocrypt/src/misc.cpp +++ b/extra/yassl/taocrypt/src/misc.cpp @@ -27,36 +27,9 @@ #include // for NewHandler -void* operator new(size_t sz, TaoCrypt::new_t) -{ - void* ptr = ::operator new(sz); - - if (!ptr) abort(); - - return ptr; -} - -void* operator new[](size_t sz, TaoCrypt::new_t tc) -{ -#if defined(_MSC_VER) && (_MSC_VER < 1300) - void* ptr = ::operator new(sz); // no ::operator new[] -#else - void* ptr = ::operator new[](sz); -#endif - - if (!ptr) abort(); - - return ptr; -} - - - namespace TaoCrypt { -new_t tc; // for library new - - inline void XorWords(word* r, const word* a, unsigned int n) { for (unsigned int i=0; i::pointer StdReallocate >(AllocatorWithCleanup&, unsigned char*, AllocatorWithCleanup::size_type, AllocatorWithCleanup::size_type, bool); template AllocatorWithCleanup::pointer StdReallocate >(AllocatorWithCleanup&, unsigned int*, AllocatorWithCleanup::size_type, AllocatorWithCleanup::size_type, bool); -template class AbstractGroup; -template class AbstractRing; template class RSA_Decryptor; template class RSA_Encryptor; template class RSA_Encryptor; @@ -227,11 +224,7 @@ template class RSA_Encryptor; namespace mySTL { template TaoCrypt::Integer* uninit_copy(TaoCrypt::Integer*, TaoCrypt::Integer*, TaoCrypt::Integer*); template TaoCrypt::Integer* uninit_fill_n(TaoCrypt::Integer*, unsigned int, TaoCrypt::Integer const&); -template TaoCrypt::WindowSlider* uninit_copy(TaoCrypt::WindowSlider*, TaoCrypt::WindowSlider*, TaoCrypt::WindowSlider*); -template vector* uninit_fill_n*, unsigned int, vector >(vector*, unsigned int, vector const&); template void destroy(TaoCrypt::Integer*, TaoCrypt::Integer*); -template void destroy(TaoCrypt::WindowSlider*, TaoCrypt::WindowSlider*); -template void destroy*>(vector*, vector*); } #endif diff --git a/mysql-test/r/lock.result b/mysql-test/r/lock.result index 16c92fa201f..a1efb1a8e69 100644 --- a/mysql-test/r/lock.result +++ b/mysql-test/r/lock.result @@ -47,3 +47,13 @@ unlock tables; lock tables t1 write, t1 as t1_alias read; insert into t1 select index1,nr from t1 as t1_alias; drop table t1,t2; +create table t1 ( a int(11) not null auto_increment, primary key(a)); +create table t2 ( a int(11) not null auto_increment, primary key(a)); +lock tables t1 write, t2 read; +delete from t1 using t1,t2 where t1.a=t2.a; +delete t1 from t1,t2 where t1.a=t2.a; +delete from t2 using t1,t2 where t1.a=t2.a; +ERROR HY000: Table 't2' was locked with a READ lock and can't be updated +delete t2 from t1,t2 where t1.a=t2.a; +ERROR HY000: Table 't2' was locked with a READ lock and can't be updated +drop table t1,t2; diff --git a/mysql-test/r/rpl_log.result b/mysql-test/r/rpl_log.result index 5d61746b984..e150cf53585 100644 --- a/mysql-test/r/rpl_log.result +++ b/mysql-test/r/rpl_log.result @@ -68,14 +68,18 @@ master-bin.000002 260 Query 1 346 use `test`; create table t1 (n int) master-bin.000002 346 Query 1 434 use `test`; insert into t1 values (1) master-bin.000002 434 Query 1 510 use `test`; drop table t1 show binary logs; -Log_name -master-bin.000001 -master-bin.000002 +Log_name File_size +master-bin.000001 0 +master-bin.000002 510 +Warnings: +Error 29 File 'master-bin.000001' not found (Errcode: 2) start slave; show binary logs; -Log_name -slave-bin.000001 -slave-bin.000002 +Log_name File_size +slave-bin.000001 0 +slave-bin.000002 348 +Warnings: +Error 29 File 'slave-bin.000001' not found (Errcode: 2) show binlog events in 'slave-bin.000001' from 4; Log_name Pos Event_type Server_id End_log_pos Info slave-bin.000001 4 Format_desc 2 98 Server ver: VERSION, Binlog ver: 4 diff --git a/mysql-test/r/rpl_rotate_logs.result b/mysql-test/r/rpl_rotate_logs.result index de177d12196..b9724386909 100644 --- a/mysql-test/r/rpl_rotate_logs.result +++ b/mysql-test/r/rpl_rotate_logs.result @@ -26,10 +26,13 @@ create table t2(m int not null auto_increment primary key); insert into t2 values (34),(67),(123); flush logs; show binary logs; -Log_name -master-bin.000001 -master-bin.000002 -master-bin.000003 +Log_name File_size +master-bin.000001 0 +master-bin.000002 0 +master-bin.000003 98 +Warnings: +Error 29 File 'master-bin.000001' not found (Errcode: 2) +Error 29 File 'master-bin.000002' not found (Errcode: 2) create table t3 select * from temp_table; select * from t3; a @@ -42,18 +45,22 @@ set global sql_slave_skip_counter=1; start slave; purge master logs to 'master-bin.000002'; show master logs; -Log_name -master-bin.000002 -master-bin.000003 +Log_name File_size +master-bin.000002 0 +master-bin.000003 407 +Warnings: +Error 29 File 'master-bin.000002' not found (Errcode: 2) purge binary logs to 'master-bin.000002'; show binary logs; -Log_name -master-bin.000002 -master-bin.000003 +Log_name File_size +master-bin.000002 0 +master-bin.000003 407 +Warnings: +Error 29 File 'master-bin.000002' not found (Errcode: 2) purge master logs before now(); show binary logs; -Log_name -master-bin.000003 +Log_name File_size +master-bin.000003 407 insert into t2 values (65); show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master @@ -73,10 +80,13 @@ count(*) 100 create table t4 select * from temp_table; show binary logs; -Log_name -master-bin.000003 -master-bin.000004 -master-bin.000005 +Log_name File_size +master-bin.000003 0 +master-bin.000004 0 +master-bin.000005 2032 +Warnings: +Error 29 File 'master-bin.000003' not found (Errcode: 2) +Error 29 File 'master-bin.000004' not found (Errcode: 2) show master status; File Position Binlog_Do_DB Binlog_Ignore_DB master-bin.000005 2032 diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result index cf0e0e8f564..1d2fb5989a5 100644 --- a/mysql-test/r/trigger.result +++ b/mysql-test/r/trigger.result @@ -140,6 +140,48 @@ drop trigger t1.trg1; drop trigger t1.trg2; drop trigger t1.trg3; drop table t1; +create table t1 (id int not null primary key, data int); +create trigger t1_bi before insert on t1 for each row +set @log:= concat(@log, "(BEFORE_INSERT: new=(id=", new.id, ", data=", new.data,"))"); +create trigger t1_ai after insert on t1 for each row +set @log:= concat(@log, "(AFTER_INSERT: new=(id=", new.id, ", data=", new.data,"))"); +create trigger t1_bu before update on t1 for each row +set @log:= concat(@log, "(BEFORE_UPDATE: old=(id=", old.id, ", data=", old.data, +") new=(id=", new.id, ", data=", new.data,"))"); +create trigger t1_au after update on t1 for each row +set @log:= concat(@log, "(AFTER_UPDATE: old=(id=", old.id, ", data=", old.data, +") new=(id=", new.id, ", data=", new.data,"))"); +create trigger t1_bd before delete on t1 for each row +set @log:= concat(@log, "(BEFORE_DELETE: old=(id=", old.id, ", data=", old.data,"))"); +create trigger t1_ad after delete on t1 for each row +set @log:= concat(@log, "(AFTER_DELETE: old=(id=", old.id, ", data=", old.data,"))"); +set @log:= ""; +insert into t1 values (1, 1); +select @log; +@log +(BEFORE_INSERT: new=(id=1, data=1))(AFTER_INSERT: new=(id=1, data=1)) +set @log:= ""; +insert ignore t1 values (1, 2); +select @log; +@log +(BEFORE_INSERT: new=(id=1, data=2)) +set @log:= ""; +replace t1 values (1, 3), (2, 2); +select @log; +@log +(BEFORE_INSERT: new=(id=1, data=3))(BEFORE_UPDATE: old=(id=1, data=1) new=(id=1, data=3))(AFTER_UPDATE: old=(id=1, data=1) new=(id=1, data=3))(BEFORE_INSERT: new=(id=2, data=2))(AFTER_INSERT: new=(id=2, data=2)) +alter table t1 add ts timestamp default now(); +set @log:= ""; +replace t1 (id, data) values (1, 4); +select @log; +@log +(BEFORE_INSERT: new=(id=1, data=4))(BEFORE_DELETE: old=(id=1, data=3))(AFTER_DELETE: old=(id=1, data=3))(AFTER_INSERT: new=(id=1, data=4)) +set @log:= ""; +insert into t1 (id, data) values (1, 5), (3, 3) on duplicate key update data= data + 2; +select @log; +@log +(BEFORE_INSERT: new=(id=1, data=5))(BEFORE_UPDATE: old=(id=1, data=4) new=(id=1, data=6))(AFTER_UPDATE: old=(id=1, data=4) new=(id=1, data=6))(BEFORE_INSERT: new=(id=3, data=3))(AFTER_INSERT: new=(id=3, data=3)) +drop table t1; create table t1 (i int); create trigger trg before insert on t1 for each row set @a:= old.i; ERROR HY000: There is no OLD row in on INSERT trigger @@ -206,3 +248,70 @@ create table t1 (i int); create trigger trg1 before insert on t1 for each row set @a:= 1; drop database mysqltest; use test; +create table t1 (i int, j int default 10, k int not null, key (k)); +create table t2 (i int); +insert into t1 (i, k) values (1, 1); +insert into t2 values (1); +create trigger trg1 before update on t1 for each row set @a:= @a + new.j - old.j; +create trigger trg2 after update on t1 for each row set @b:= "Fired"; +set @a:= 0, @b:= ""; +update t1, t2 set j = j + 10 where t1.i = t2.i; +select @a, @b; +@a @b +10 Fired +insert into t1 values (2, 13, 2); +insert into t2 values (2); +set @a:= 0, @b:= ""; +update t1, t2 set j = j + 15 where t1.i = t2.i and t1.k >= 2; +select @a, @b; +@a @b +15 Fired +create trigger trg3 before delete on t1 for each row set @c:= @c + old.j; +create trigger trg4 before delete on t2 for each row set @d:= @d + old.i; +create trigger trg5 after delete on t1 for each row set @e:= "After delete t1 fired"; +create trigger trg6 after delete on t2 for each row set @f:= "After delete t2 fired"; +set @c:= 0, @d:= 0, @e:= "", @f:= ""; +delete t1, t2 from t1, t2 where t1.i = t2.i; +select @c, @d, @e, @f; +@c @d @e @f +48 3 After delete t1 fired After delete t2 fired +drop table t1, t2; +create table t1 (i int, j int default 10)| +create table t2 (i int)| +insert into t2 values (1), (2)| +create trigger trg1 before insert on t1 for each row +begin +if new.i = 1 then +set new.j := 1; +end if; +end| +create trigger trg2 after insert on t1 for each row set @a:= 1| +set @a:= 0| +insert into t1 (i) select * from t2| +select * from t1| +i j +1 1 +2 10 +select @a| +@a +1 +drop table t1, t2| +create table t1 (i int, j int, k int); +create trigger trg1 before insert on t1 for each row set new.k = new.i; +create trigger trg2 after insert on t1 for each row set @b:= "Fired"; +set @b:=""; +load data infile '../../std_data/rpl_loaddata.dat' into table t1 (@a, i); +select *, @b from t1; +i j k @b +10 NULL 10 Fired +15 NULL 15 Fired +set @b:=""; +load data infile '../../std_data/loaddata5.dat' into table t1 fields terminated by '' enclosed by '' (i, j); +select *, @b from t1; +i j k @b +10 NULL 10 Fired +15 NULL 15 Fired +1 2 1 Fired +3 4 3 Fired +5 6 5 Fired +drop table t1; diff --git a/mysql-test/t/lock.test b/mysql-test/t/lock.test index faa1fa3ac25..127cbb54a88 100644 --- a/mysql-test/t/lock.test +++ b/mysql-test/t/lock.test @@ -59,3 +59,17 @@ unlock tables; lock tables t1 write, t1 as t1_alias read; insert into t1 select index1,nr from t1 as t1_alias; drop table t1,t2; + +# +# Bug7241 - Invalid response when DELETE .. USING and LOCK TABLES used. +# +create table t1 ( a int(11) not null auto_increment, primary key(a)); +create table t2 ( a int(11) not null auto_increment, primary key(a)); +lock tables t1 write, t2 read; +delete from t1 using t1,t2 where t1.a=t2.a; +delete t1 from t1,t2 where t1.a=t2.a; +--error 1099 +delete from t2 using t1,t2 where t1.a=t2.a; +--error 1099 +delete t2 from t1,t2 where t1.a=t2.a; +drop table t1,t2; diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test index 53144cf3591..79f65bba678 100644 --- a/mysql-test/t/trigger.test +++ b/mysql-test/t/trigger.test @@ -150,6 +150,55 @@ drop trigger t1.trg3; drop table t1; +# Let us test how triggers work for special forms of INSERT such as +# REPLACE and INSERT ... ON DUPLICATE KEY UPDATE +create table t1 (id int not null primary key, data int); +create trigger t1_bi before insert on t1 for each row + set @log:= concat(@log, "(BEFORE_INSERT: new=(id=", new.id, ", data=", new.data,"))"); +create trigger t1_ai after insert on t1 for each row + set @log:= concat(@log, "(AFTER_INSERT: new=(id=", new.id, ", data=", new.data,"))"); +create trigger t1_bu before update on t1 for each row + set @log:= concat(@log, "(BEFORE_UPDATE: old=(id=", old.id, ", data=", old.data, + ") new=(id=", new.id, ", data=", new.data,"))"); +create trigger t1_au after update on t1 for each row + set @log:= concat(@log, "(AFTER_UPDATE: old=(id=", old.id, ", data=", old.data, + ") new=(id=", new.id, ", data=", new.data,"))"); +create trigger t1_bd before delete on t1 for each row + set @log:= concat(@log, "(BEFORE_DELETE: old=(id=", old.id, ", data=", old.data,"))"); +create trigger t1_ad after delete on t1 for each row + set @log:= concat(@log, "(AFTER_DELETE: old=(id=", old.id, ", data=", old.data,"))"); +# Simple INSERT - both triggers should be called +set @log:= ""; +insert into t1 values (1, 1); +select @log; +# INSERT IGNORE for already existing key - only before trigger should fire +set @log:= ""; +insert ignore t1 values (1, 2); +select @log; +# REPLACE: before insert trigger should be called for both records, +# but then for first one update will be executed (and both update +# triggers should fire). For second after insert trigger will be +# called as for usual insert +set @log:= ""; +replace t1 values (1, 3), (2, 2); +select @log; +# Now let us change table in such way that REPLACE on won't be executed +# using update. +alter table t1 add ts timestamp default now(); +set @log:= ""; +# This REPLACE should be executed via DELETE and INSERT so proper +# triggers should be invoked. +replace t1 (id, data) values (1, 4); +select @log; +# Finally let us test INSERT ... ON DUPLICATE KEY UPDATE ... +set @log:= ""; +insert into t1 (id, data) values (1, 5), (3, 3) on duplicate key update data= data + 2; +select @log; + +# This also drops associated triggers +drop table t1; + + # # Test of wrong column specifiers in triggers # @@ -249,3 +298,72 @@ create trigger trg1 before insert on t1 for each row set @a:= 1; # This should succeed drop database mysqltest; use test; + +# Test for bug #5860 "Multi-table UPDATE does not activate update triggers" +# We will also test how delete triggers wor for multi-table DELETE. +create table t1 (i int, j int default 10, k int not null, key (k)); +create table t2 (i int); +insert into t1 (i, k) values (1, 1); +insert into t2 values (1); +create trigger trg1 before update on t1 for each row set @a:= @a + new.j - old.j; +create trigger trg2 after update on t1 for each row set @b:= "Fired"; +set @a:= 0, @b:= ""; +# Check that trigger works in case of update on the fly +update t1, t2 set j = j + 10 where t1.i = t2.i; +select @a, @b; +insert into t1 values (2, 13, 2); +insert into t2 values (2); +set @a:= 0, @b:= ""; +# And now let us check that triggers work in case of multi-update which +# is done through temporary tables... +update t1, t2 set j = j + 15 where t1.i = t2.i and t1.k >= 2; +select @a, @b; +# Let us test delete triggers for multi-delete now. +# We create triggers for both tables because we want test how they +# work in both on-the-fly and via-temp-tables cases. +create trigger trg3 before delete on t1 for each row set @c:= @c + old.j; +create trigger trg4 before delete on t2 for each row set @d:= @d + old.i; +create trigger trg5 after delete on t1 for each row set @e:= "After delete t1 fired"; +create trigger trg6 after delete on t2 for each row set @f:= "After delete t2 fired"; +set @c:= 0, @d:= 0, @e:= "", @f:= ""; +delete t1, t2 from t1, t2 where t1.i = t2.i; +select @c, @d, @e, @f; +# This also will drop triggers +drop table t1, t2; + +# Test for bug #6812 "Triggers are not activated for INSERT ... SELECT". +# (We also check the fact that trigger modifies some field does not affect +# value of next record inserted). +delimiter |; +create table t1 (i int, j int default 10)| +create table t2 (i int)| +insert into t2 values (1), (2)| +create trigger trg1 before insert on t1 for each row +begin + if new.i = 1 then + set new.j := 1; + end if; +end| +create trigger trg2 after insert on t1 for each row set @a:= 1| +set @a:= 0| +insert into t1 (i) select * from t2| +select * from t1| +select @a| +# This also will drop triggers +drop table t1, t2| +delimiter ;| + +# Test for bug #8755 "Trigger is not activated by LOAD DATA" +create table t1 (i int, j int, k int); +create trigger trg1 before insert on t1 for each row set new.k = new.i; +create trigger trg2 after insert on t1 for each row set @b:= "Fired"; +set @b:=""; +# Test triggers with file with separators +load data infile '../../std_data/rpl_loaddata.dat' into table t1 (@a, i); +select *, @b from t1; +set @b:=""; +# Test triggers with fixed size row file +load data infile '../../std_data/loaddata5.dat' into table t1 fields terminated by '' enclosed by '' (i, j); +select *, @b from t1; +# This also will drop triggers +drop table t1; diff --git a/sql/item.cc b/sql/item.cc index a28cc261b3c..69b1b78a961 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4554,40 +4554,40 @@ void Item_insert_value::print(String *str) /* - Bind item representing field of row being changed in trigger - to appropriate Field object. + Find index of Field object which will be appropriate for item + representing field of row being changed in trigger. SYNOPSIS setup_field() thd - current thread context table - table of trigger (and where we looking for fields) - event - type of trigger event NOTE This function does almost the same as fix_fields() for Item_field - but is invoked during trigger definition parsing and takes TABLE - object as its argument. If proper field was not found in table - error will be reported at fix_fields() time. + but is invoked right after trigger definition parsing. Since at + this stage we can't say exactly what Field object (corresponding + to TABLE::record[0] or TABLE::record[1]) should be bound to this + Item, we only find out index of the Field and then select concrete + Field object in fix_fields() (by that time Table_trigger_list::old_field/ + new_field should point to proper array of Fields). + It also binds Item_trigger_field to Table_triggers_list object for + table of trigger which uses this item. */ -void Item_trigger_field::setup_field(THD *thd, TABLE *table, - enum trg_event_type event) + +void Item_trigger_field::setup_field(THD *thd, TABLE *table) { - uint field_idx= (uint)-1; bool save_set_query_id= thd->set_query_id; /* TODO: Think more about consequences of this step. */ thd->set_query_id= 0; - - if (find_field_in_real_table(thd, table, field_name, - strlen(field_name), 0, 0, - &field_idx)) - { - field= (row_version == OLD_ROW && event == TRG_EVENT_UPDATE) ? - table->triggers->old_field[field_idx] : - table->field[field_idx]; - } - + /* + Try to find field by its name and if it will be found + set field_idx properly. + */ + (void)find_field_in_real_table(thd, table, field_name, strlen(field_name), + 0, 0, &field_idx); thd->set_query_id= save_set_query_id; + triggers= table->triggers; } @@ -4612,9 +4612,10 @@ bool Item_trigger_field::fix_fields(THD *thd, */ DBUG_ASSERT(fixed == 0); - if (field) + if (field_idx != (uint)-1) { - // QQ: May be this should be moved to setup_field? + field= (row_version == OLD_ROW) ? triggers->old_field[field_idx] : + triggers->new_field[field_idx]; set_field(field); fixed= 1; return 0; diff --git a/sql/item.h b/sql/item.h index 18a81dcaa03..f8fe05cfdb2 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1632,13 +1632,18 @@ enum trg_event_type TRG_EVENT_INSERT= 0 , TRG_EVENT_UPDATE= 1, TRG_EVENT_DELETE= 2 }; +class Table_triggers_list; + /* Represents NEW/OLD version of field of row which is changed/read in trigger. - Note: For this item actual binding to Field object happens not during - fix_fields() (like for Item_field) but during parsing of trigger - definition, when table is opened, with special setup_field() call. + Note: For this item main part of actual binding to Field object happens + not during fix_fields() call (like for Item_field) but right after + parsing of trigger definition, when table is opened, with special + setup_field() call. On fix_fields() stage we simply choose one of + two Field instances representing either OLD or NEW version of this + field. */ class Item_trigger_field : public Item_field { @@ -1648,13 +1653,17 @@ public: row_version_type row_version; /* Next in list of all Item_trigger_field's in trigger */ Item_trigger_field *next_trg_field; + /* Index of the field in the TABLE::field array */ + uint field_idx; + /* Pointer to Table_trigger_list object for table of this trigger */ + Table_triggers_list *triggers; Item_trigger_field(row_version_type row_ver_par, const char *field_name_par): Item_field((const char *)NULL, (const char *)NULL, field_name_par), - row_version(row_ver_par) + row_version(row_ver_par), field_idx((uint)-1) {} - void setup_field(THD *thd, TABLE *table, enum trg_event_type event); + void setup_field(THD *thd, TABLE *table); enum Type type() const { return TRIGGER_FIELD_ITEM; } bool eq(const Item *item, bool binary_cmp) const; bool fix_fields(THD *, struct st_table_list *, Item **); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 645e835d9ca..5d11a047a8f 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -924,10 +924,18 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table, bool return_if_owned_by_thd); bool close_cached_tables(THD *thd, bool wait_for_refresh, TABLE_LIST *tables); void copy_field_from_tmp_record(Field *field,int offset); -bool fill_record(THD *thd, List &fields, List &values, - bool ignore_errors); bool fill_record(THD *thd, Field **field, List &values, bool ignore_errors); +bool fill_record_n_invoke_before_triggers(THD *thd, List &fields, + List &values, + bool ignore_errors, + Table_triggers_list *triggers, + enum trg_event_type event); +bool fill_record_n_invoke_before_triggers(THD *thd, Field **field, + List &values, + bool ignore_errors, + Table_triggers_list *triggers, + enum trg_event_type event); OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *wild); inline TABLE_LIST *find_table_in_global_list(TABLE_LIST *table, diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 29d9a7bf9c4..2e9cf1ae40d 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -3813,7 +3813,7 @@ err_no_arena: TRUE error occured */ -bool +static bool fill_record(THD * thd, List &fields, List &values, bool ignore_errors) { @@ -3839,6 +3839,41 @@ fill_record(THD * thd, List &fields, List &values, } +/* + Fill fields in list with values from the list of items and invoke + before triggers. + + SYNOPSIS + fill_record_n_invoke_before_triggers() + thd thread context + fields Item_fields list to be filled + values values to fill with + ignore_errors TRUE if we should ignore errors + triggers object holding list of triggers to be invoked + event event type for triggers to be invoked + + NOTE + This function assumes that fields which values will be set and triggers + to be invoked belong to the same table, and that TABLE::record[0] and + record[1] buffers correspond to new and old versions of row respectively. + + RETURN + FALSE OK + TRUE error occured +*/ + +bool +fill_record_n_invoke_before_triggers(THD *thd, List &fields, + List &values, bool ignore_errors, + Table_triggers_list *triggers, + enum trg_event_type event) +{ + return (fill_record(thd, fields, values, ignore_errors) || + triggers && triggers->process_triggers(thd, event, + TRG_ACTION_BEFORE, TRUE)); +} + + /* Fill field buffer with values from Field list @@ -3875,6 +3910,41 @@ fill_record(THD *thd, Field **ptr, List &values, bool ignore_errors) } +/* + Fill fields in array with values from the list of items and invoke + before triggers. + + SYNOPSIS + fill_record_n_invoke_before_triggers() + thd thread context + ptr NULL-ended array of fields to be filled + values values to fill with + ignore_errors TRUE if we should ignore errors + triggers object holding list of triggers to be invoked + event event type for triggers to be invoked + + NOTE + This function assumes that fields which values will be set and triggers + to be invoked belong to the same table, and that TABLE::record[0] and + record[1] buffers correspond to new and old versions of row respectively. + + RETURN + FALSE OK + TRUE error occured +*/ + +bool +fill_record_n_invoke_before_triggers(THD *thd, Field **ptr, + List &values, bool ignore_errors, + Table_triggers_list *triggers, + enum trg_event_type event) +{ + return (fill_record(thd, ptr, values, ignore_errors) || + triggers && triggers->process_triggers(thd, event, + TRG_ACTION_BEFORE, TRUE)); +} + + static void mysql_rm_tmp_tables(void) { uint i, idx; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index ca7bf174abf..97830f7ec8f 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -176,13 +176,24 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, if (!(select && select->skip_record())&& !thd->net.report_error ) { - if (table->triggers) - table->triggers->process_triggers(thd, TRG_EVENT_DELETE, - TRG_ACTION_BEFORE); + if (table->triggers && + table->triggers->process_triggers(thd, TRG_EVENT_DELETE, + TRG_ACTION_BEFORE, FALSE)) + { + error= 1; + break; + } if (!(error=table->file->delete_row(table->record[0]))) { deleted++; + if (table->triggers && + table->triggers->process_triggers(thd, TRG_EVENT_DELETE, + TRG_ACTION_AFTER, FALSE)) + { + error= 1; + break; + } if (!--limit && using_limit) { error= -1; @@ -203,10 +214,6 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, error= 1; break; } - - if (table->triggers) - table->triggers->process_triggers(thd, TRG_EVENT_DELETE, - TRG_ACTION_AFTER); } else table->file->unlock_row(); // Row failed selection, release lock on it @@ -509,9 +516,19 @@ bool multi_delete::send_data(List &values) if (secure_counter < 0) { /* If this is the table we are scanning */ + if (table->triggers && + table->triggers->process_triggers(thd, TRG_EVENT_DELETE, + TRG_ACTION_BEFORE, FALSE)) + DBUG_RETURN(1); table->status|= STATUS_DELETED; if (!(error=table->file->delete_row(table->record[0]))) + { deleted++; + if (table->triggers && + table->triggers->process_triggers(thd, TRG_EVENT_DELETE, + TRG_ACTION_AFTER, FALSE)) + DBUG_RETURN(1); + } else if (!table_being_deleted->next_local || table_being_deleted->table->file->has_transactions()) { @@ -614,12 +631,26 @@ int multi_delete::do_deletes(bool from_send_error) info.ignore_not_found_rows= 1; while (!(local_error=info.read_record(&info)) && !thd->killed) { + if (table->triggers && + table->triggers->process_triggers(thd, TRG_EVENT_DELETE, + TRG_ACTION_BEFORE, FALSE)) + { + local_error= 1; + break; + } if ((local_error=table->file->delete_row(table->record[0]))) { table->file->print_error(local_error,MYF(0)); break; } deleted++; + if (table->triggers && + table->triggers->process_triggers(thd, TRG_EVENT_DELETE, + TRG_ACTION_AFTER, FALSE)) + { + local_error= 1; + break; + } } end_read_record(&info); if (thd->killed && !local_error) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 0bd9099ede1..6db7e6a6b18 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -398,7 +398,9 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, if (fields.elements || !value_count) { restore_record(table,s->default_values); // Get empty record - if (fill_record(thd, fields, *values, 0)) + if (fill_record_n_invoke_before_triggers(thd, fields, *values, 0, + table->triggers, + TRG_EVENT_INSERT)) { if (values_list.elements != 1 && !thd->net.report_error) { @@ -419,8 +421,17 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, if (thd->used_tables) // Column used in values() restore_record(table,s->default_values); // Get empty record else - table->record[0][0]= table->s->default_values[0]; // Fix delete marker - if (fill_record(thd, table->field, *values, 0)) + { + /* + Fix delete marker. No need to restore rest of record since it will + be overwritten by fill_record() anyway (and fill_record() does not + use default values in this case). + */ + table->record[0][0]= table->s->default_values[0]; + } + if (fill_record_n_invoke_before_triggers(thd, table->field, *values, 0, + table->triggers, + TRG_EVENT_INSERT)) { if (values_list.elements != 1 && ! thd->net.report_error) { @@ -432,14 +443,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, } } - /* - FIXME: Actually we should do this before - check_that_all_fields_are_given_values Or even go into write_record ? - */ - if (table->triggers) - table->triggers->process_triggers(thd, TRG_EVENT_INSERT, - TRG_ACTION_BEFORE); - if ((res= table_list->view_check_option(thd, (values_list.elements == 1 ? 0 : @@ -473,9 +476,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, if (error) break; thd->row_count++; - - if (table->triggers) - table->triggers->process_triggers(thd, TRG_EVENT_INSERT, TRG_ACTION_AFTER); } /* @@ -802,15 +802,35 @@ static int last_uniq_key(TABLE *table,uint keynr) /* - Write a record to table with optional deleting of conflicting records + Write a record to table with optional deleting of conflicting records, + invoke proper triggers if needed. - Sets thd->no_trans_update if table which is updated didn't have transactions + SYNOPSIS + write_record() + thd - thread context + table - table to which record should be written + info - COPY_INFO structure describing handling of duplicates + and which is used for counting number of records inserted + and deleted. + + NOTE + Once this record will be written to table after insert trigger will + be invoked. If instead of inserting new record we will update old one + then both on update triggers will work instead. Similarly both on + delete triggers will be invoked if we will delete conflicting records. + + Sets thd->no_trans_update if table which is updated didn't have + transactions. + + RETURN VALUE + 0 - success + non-0 - error */ int write_record(THD *thd, TABLE *table,COPY_INFO *info) { - int error; + int error, trg_error= 0; char *key=0; DBUG_ENTER("write_record"); @@ -881,25 +901,33 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) restore_record(table,record[1]); DBUG_ASSERT(info->update_fields->elements == info->update_values->elements); - if (fill_record(thd, *info->update_fields, *info->update_values, 0)) - goto err; + if (fill_record_n_invoke_before_triggers(thd, *info->update_fields, + *info->update_values, 0, + table->triggers, + TRG_EVENT_UPDATE)) + goto before_trg_err; /* CHECK OPTION for VIEW ... ON DUPLICATE KEY UPDATE ... */ if (info->view && (res= info->view->view_check_option(current_thd, info->ignore)) == VIEW_CHECK_SKIP) - break; + goto ok_or_after_trg_err; if (res == VIEW_CHECK_ERROR) - goto err; + goto before_trg_err; if ((error=table->file->update_row(table->record[1],table->record[0]))) { if ((error == HA_ERR_FOUND_DUPP_KEY) && info->ignore) - break; + goto ok_or_after_trg_err; goto err; } info->updated++; - break; + + trg_error= (table->triggers && + table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, + TRG_ACTION_AFTER, TRUE)); + info->copied++; + goto ok_or_after_trg_err; } else /* DUP_REPLACE */ { @@ -916,20 +944,48 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) (table->timestamp_field_type == TIMESTAMP_NO_AUTO_SET || table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH)) { + if (table->triggers && + table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, + TRG_ACTION_BEFORE, TRUE)) + goto before_trg_err; if ((error=table->file->update_row(table->record[1], table->record[0]))) goto err; info->deleted++; - break; /* Update logfile and count */ + trg_error= (table->triggers && + table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, + TRG_ACTION_AFTER, + TRUE)); + /* Update logfile and count */ + info->copied++; + goto ok_or_after_trg_err; + } + else + { + if (table->triggers && + table->triggers->process_triggers(thd, TRG_EVENT_DELETE, + TRG_ACTION_BEFORE, TRUE)) + goto before_trg_err; + if ((error=table->file->delete_row(table->record[1]))) + goto err; + info->deleted++; + if (!table->file->has_transactions()) + thd->no_trans_update= 1; + if (table->triggers && + table->triggers->process_triggers(thd, TRG_EVENT_DELETE, + TRG_ACTION_AFTER, TRUE)) + { + trg_error= 1; + goto ok_or_after_trg_err; + } + /* Let us attempt do write_row() once more */ } - else if ((error=table->file->delete_row(table->record[1]))) - goto err; - info->deleted++; - if (!table->file->has_transactions()) - thd->no_trans_update= 1; } } info->copied++; + trg_error= (table->triggers && + table->triggers->process_triggers(thd, TRG_EVENT_INSERT, + TRG_ACTION_AFTER, TRUE)); } else if ((error=table->file->write_row(table->record[0]))) { @@ -939,18 +995,27 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) table->file->restore_auto_increment(); } else + { info->copied++; + trg_error= (table->triggers && + table->triggers->process_triggers(thd, TRG_EVENT_INSERT, + TRG_ACTION_AFTER, TRUE)); + } + +ok_or_after_trg_err: if (key) my_safe_afree(key,table->s->max_unique_length,MAX_KEY_LENGTH); if (!table->file->has_transactions()) thd->no_trans_update= 1; - DBUG_RETURN(0); + DBUG_RETURN(trg_error); err: - if (key) - my_safe_afree(key,table->s->max_unique_length,MAX_KEY_LENGTH); info->last_errno= error; table->file->print_error(error,MYF(0)); + +before_trg_err: + if (key) + my_safe_afree(key, table->s->max_unique_length, MAX_KEY_LENGTH); DBUG_RETURN(1); } @@ -2014,12 +2079,27 @@ bool select_insert::send_data(List &values) DBUG_RETURN(1); } } - if (!(error= write_record(thd, table,&info)) && table->next_number_field) + if (!(error= write_record(thd, table, &info))) { - /* Clear for next record */ - table->next_number_field->reset(); - if (! last_insert_id && thd->insert_id_used) - last_insert_id=thd->insert_id(); + if (table->triggers) + { + /* + If triggers exist then whey can modify some fields which were not + originally touched by INSERT ... SELECT, so we have to restore + their original values for the next row. + */ + restore_record(table, s->default_values); + } + if (table->next_number_field) + { + /* + Clear auto-increment field for the next record, if triggers are used + we will clear it twice, but this should be cheap. + */ + table->next_number_field->reset(); + if (!last_insert_id && thd->insert_id_used) + last_insert_id= thd->insert_id(); + } } DBUG_RETURN(error); } @@ -2028,9 +2108,11 @@ bool select_insert::send_data(List &values) void select_insert::store_values(List &values) { if (fields->elements) - fill_record(thd, *fields, values, 1); + fill_record_n_invoke_before_triggers(thd, *fields, values, 1, + table->triggers, TRG_EVENT_INSERT); else - fill_record(thd, table->field, values, 1); + fill_record_n_invoke_before_triggers(thd, table->field, values, 1, + table->triggers, TRG_EVENT_INSERT); } void select_insert::send_error(uint errcode,const char *err) @@ -2173,7 +2255,8 @@ select_create::prepare(List &values, SELECT_LEX_UNIT *u) void select_create::store_values(List &values) { - fill_record(thd, field, values, 1); + fill_record_n_invoke_before_triggers(thd, field, values, 1, + table->triggers, TRG_EVENT_INSERT); } diff --git a/sql/sql_load.cc b/sql/sql_load.cc index c827bbace3e..1545055f475 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -21,6 +21,8 @@ #include #include #include "sql_repl.h" +#include "sp_head.h" +#include "sql_trigger.h" class READ_INFO { File file; @@ -568,7 +570,11 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, ER(ER_WARN_TOO_MANY_RECORDS), thd->row_count); } - if (fill_record(thd, set_fields, set_values, ignore_check_option_errors)) + if (thd->killed || + fill_record_n_invoke_before_triggers(thd, set_fields, set_values, + ignore_check_option_errors, + table->triggers, + TRG_EVENT_INSERT)) DBUG_RETURN(1); switch (table_list->view_check_option(thd, @@ -580,7 +586,7 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, DBUG_RETURN(-1); } - if (thd->killed || write_record(thd,table,&info)) + if (write_record(thd, table, &info)) DBUG_RETURN(1); thd->no_trans_update= no_trans_update; @@ -592,8 +598,10 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, */ if (!id && thd->insert_id_used) id= thd->last_insert_id; - if (table->next_number_field) - table->next_number_field->reset(); // Clear for next record + /* + We don't need to reset auto-increment field since we are restoring + its default value at the beginning of each loop iteration. + */ if (read_info.next_line()) // Skip to next line break; if (read_info.line_cuted) @@ -725,7 +733,11 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, } } - if (fill_record(thd, set_fields, set_values, ignore_check_option_errors)) + if (thd->killed || + fill_record_n_invoke_before_triggers(thd, set_fields, set_values, + ignore_check_option_errors, + table->triggers, + TRG_EVENT_INSERT)) DBUG_RETURN(1); switch (table_list->view_check_option(thd, @@ -738,7 +750,7 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, } - if (thd->killed || write_record(thd, table, &info)) + if (write_record(thd, table, &info)) DBUG_RETURN(1); /* If auto_increment values are used, save the first one @@ -748,8 +760,10 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, */ if (!id && thd->insert_id_used) id= thd->last_insert_id; - if (table->next_number_field) - table->next_number_field->reset(); // Clear for next record + /* + We don't need to reset auto-increment field since we are restoring + its default value at the beginning of each loop iteration. + */ thd->no_trans_update= no_trans_update; if (read_info.next_line()) // Skip to next line break; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 0e8f7746f0f..7078c8e7181 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2326,6 +2326,10 @@ mysql_execute_command(THD *thd) } #endif /* !HAVE_REPLICATION */ + + + + /* When option readonly is set deny operations which change tables. Except for the replication thread and the 'super' users. @@ -5198,6 +5202,7 @@ void mysql_init_multi_delete(LEX *lex) lex->select_lex.select_limit= lex->unit.select_limit_cnt= HA_POS_ERROR; lex->select_lex.table_list.save_and_clear(&lex->auxilliary_table_list); + lex->lock_option= using_update_log ? TL_READ_NO_INSERT : TL_READ; lex->query_tables= 0; lex->query_tables_last= &lex->query_tables; } @@ -6776,6 +6781,14 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count) } walk->lock_type= target_tbl->lock_type; target_tbl->correspondent_table= walk; // Remember corresponding table + + /* in case of subselects, we need to set lock_type in + * corresponding table in list of all tables */ + if (walk->correspondent_table) + { + target_tbl->correspondent_table= walk->correspondent_table; + walk->correspondent_table->lock_type= walk->lock_type; + } } DBUG_RETURN(FALSE); } diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 0dcfd985f88..ca67b09fdc8 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1478,6 +1478,11 @@ bool show_binlog_info(THD* thd) bool show_binlogs(THD* thd) { IO_CACHE *index_file; + LOG_INFO cur; + IO_CACHE log; + File file; + const char *errmsg= 0; + MY_STAT stat_area; char fname[FN_REFLEN]; List field_list; uint length; @@ -1491,21 +1496,43 @@ bool show_binlogs(THD* thd) } field_list.push_back(new Item_empty_string("Log_name", 255)); + field_list.push_back(new Item_return_int("File_size", 20, + MYSQL_TYPE_LONGLONG)); if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) DBUG_RETURN(TRUE); mysql_bin_log.lock_index(); index_file=mysql_bin_log.get_index_file(); - + + mysql_bin_log.get_current_log(&cur); + int cur_dir_len = dirname_length(cur.log_file_name); + reinit_io_cache(index_file, READ_CACHE, (my_off_t) 0, 0, 0); /* The file ends with EOF or empty line */ while ((length=my_b_gets(index_file, fname, sizeof(fname))) > 1) { + fname[--length] = '\0'; /* remove the newline */ + protocol->prepare_for_resend(); int dir_len = dirname_length(fname); - /* The -1 is for removing newline from fname */ - protocol->store(fname + dir_len, length-1-dir_len, &my_charset_bin); + protocol->store(fname + dir_len, length-dir_len, &my_charset_bin); + if(!(strncmp(fname+dir_len, cur.log_file_name+cur_dir_len, length-dir_len))) + { + /* this is the active log, use the active position */ + protocol->store((ulonglong) cur.pos); + } else { + /* this is an old log, open it and find the size */ + if ((file=open_binlog(&log, fname+dir_len, &errmsg)) >= 0) + { + protocol->store((ulonglong) my_b_filelength(&log)); + end_io_cache(&log); + my_close(file, MYF(0)); + } else { + /* the file wasn't openable, but 0 is an invalid value anyway */ + protocol->store((ulonglong) 0); + } + } if (protocol->write()) goto err; } diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 670c618bec5..95524a6dfbf 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -85,7 +85,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) DBUG_RETURN(TRUE); } - if (!(table->triggers= new (&table->mem_root) Table_triggers_list())) + if (!(table->triggers= new (&table->mem_root) Table_triggers_list(table))) DBUG_RETURN(TRUE); } @@ -190,17 +190,16 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables) to other tables from trigger we won't be able to catch changes in other tables... - To simplify code a bit we have to create Fields for accessing to old row - values if we have ON UPDATE trigger. + Since we don't plan to access to contents of the fields it does not + matter that we choose for both OLD and NEW values the same versions + of Field objects here. */ - if (!old_field && lex->trg_chistics.event == TRG_EVENT_UPDATE && - prepare_old_row_accessors(table)) - return 1; + old_field= new_field= table->field; for (trg_field= (Item_trigger_field *)(lex->trg_table_fields.first); trg_field; trg_field= trg_field->next_trg_field) { - trg_field->setup_field(thd, table, lex->trg_chistics.event); + trg_field->setup_field(thd, table); if (!trg_field->fixed && trg_field->fix_fields(thd, (TABLE_LIST *)0, (Item **)0)) return 1; @@ -318,34 +317,35 @@ Table_triggers_list::~Table_triggers_list() for (int j= 0; j < 2; j++) delete bodies[i][j]; - if (old_field) - for (Field **fld_ptr= old_field; *fld_ptr; fld_ptr++) + if (record1_field) + for (Field **fld_ptr= record1_field; *fld_ptr; fld_ptr++) delete *fld_ptr; } /* - Prepare array of Field objects which will represent OLD.* row values in - ON UPDATE trigger (by referencing to record[1] instead of record[0]). + Prepare array of Field objects referencing to TABLE::record[1] instead + of record[0] (they will represent OLD.* row values in ON UPDATE trigger + and in ON DELETE trigger which will be called during REPLACE execution). SYNOPSIS - prepare_old_row_accessors() + prepare_record1_accessors() table - pointer to TABLE object for which we are creating fields. RETURN VALUE False - success True - error */ -bool Table_triggers_list::prepare_old_row_accessors(TABLE *table) +bool Table_triggers_list::prepare_record1_accessors(TABLE *table) { Field **fld, **old_fld; - if (!(old_field= (Field **)alloc_root(&table->mem_root, - (table->s->fields + 1) * - sizeof(Field*)))) + if (!(record1_field= (Field **)alloc_root(&table->mem_root, + (table->s->fields + 1) * + sizeof(Field*)))) return 1; - for (fld= table->field, old_fld= old_field; *fld; fld++, old_fld++) + for (fld= table->field, old_fld= record1_field; *fld; fld++, old_fld++) { /* QQ: it is supposed that it is ok to use this function for field @@ -406,7 +406,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, parser->type()->length)) { Table_triggers_list *triggers= - new (&table->mem_root) Table_triggers_list(); + new (&table->mem_root) Table_triggers_list(table); if (!triggers) DBUG_RETURN(1); @@ -417,8 +417,11 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, table->triggers= triggers; - /* TODO: This could be avoided if there is no ON UPDATE trigger. */ - if (triggers->prepare_old_row_accessors(table)) + /* + TODO: This could be avoided if there is no triggers + for UPDATE and DELETE. + */ + if (triggers->prepare_record1_accessors(table)) DBUG_RETURN(1); List_iterator_fast it(triggers->definitions_list); @@ -478,7 +481,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, (Item_trigger_field *)(lex.trg_table_fields.first); trg_field; trg_field= trg_field->next_trg_field) - trg_field->setup_field(thd, table, lex.trg_chistics.event); + trg_field->setup_field(thd, table); lex_end(&lex); } diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h index 90c906fc72f..d61da8ff06b 100644 --- a/sql/sql_trigger.h +++ b/sql/sql_trigger.h @@ -8,10 +8,20 @@ class Table_triggers_list: public Sql_alloc /* Triggers as SPs grouped by event, action_time */ sp_head *bodies[3][2]; /* - Copy of TABLE::Field array with field pointers set to old version - of record, used for OLD values in trigger on UPDATE. + Copy of TABLE::Field array with field pointers set to TABLE::record[1] + buffer instead of TABLE::record[0] (used for OLD values in on UPDATE + trigger and DELETE trigger when it is called for REPLACE). */ + Field **record1_field; + /* + During execution of trigger new_field and old_field should point to the + array of fields representing new or old version of row correspondingly + (so it can point to TABLE::field or to Tale_triggers_list::record1_field) + */ + Field **new_field; Field **old_field; + /* TABLE instance for which this triggers list object was created */ + TABLE *table; /* Names of triggers. Should correspond to order of triggers on definitions_list, @@ -26,8 +36,8 @@ public: */ List definitions_list; - Table_triggers_list(): - old_field(0) + Table_triggers_list(TABLE *table_arg): + record1_field(0), table(table_arg) { bzero((char *)bodies, sizeof(bodies)); } @@ -36,7 +46,8 @@ public: bool create_trigger(THD *thd, TABLE_LIST *table); bool drop_trigger(THD *thd, TABLE_LIST *table); bool process_triggers(THD *thd, trg_event_type event, - trg_action_time_type time_type) + trg_action_time_type time_type, + bool old_row_is_record1) { int res= 0; @@ -48,6 +59,17 @@ public: thd->net.no_send_ok= TRUE; #endif + if (old_row_is_record1) + { + old_field= record1_field; + new_field= table->field; + } + else + { + new_field= record1_field; + old_field= table->field; + } + /* FIXME: We should juggle with security context here (because trigger should be invoked with creator rights). @@ -79,8 +101,13 @@ public: bodies[TRG_EVENT_DELETE][TRG_ACTION_AFTER]); } + bool has_before_update_triggers() + { + return test(bodies[TRG_EVENT_UPDATE][TRG_ACTION_BEFORE]); + } + friend class Item_trigger_field; private: - bool prepare_old_row_accessors(TABLE *table); + bool prepare_record1_accessors(TABLE *table); }; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 990f22635c7..a19a3e46798 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -398,14 +398,13 @@ int mysql_update(THD *thd, if (!(select && select->skip_record())) { store_record(table,record[1]); - if (fill_record(thd, fields, values, 0)) + if (fill_record_n_invoke_before_triggers(thd, fields, values, 0, + table->triggers, + TRG_EVENT_UPDATE)) break; /* purecov: inspected */ found++; - if (table->triggers) - table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, TRG_ACTION_BEFORE); - if (compare_record(table, query_id)) { if ((res= table_list->view_check_option(thd, ignore)) != @@ -425,6 +424,14 @@ int mysql_update(THD *thd, { updated++; thd->no_trans_update= !transactional_table; + + if (table->triggers && + table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, + TRG_ACTION_AFTER, TRUE)) + { + error= 1; + break; + } } else if (!ignore || error != HA_ERR_FOUND_DUPP_KEY) { @@ -435,9 +442,6 @@ int mysql_update(THD *thd, } } - if (table->triggers) - table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, TRG_ACTION_AFTER); - if (!--limit && using_limit) { error= -1; // Simulate end of file @@ -1073,8 +1077,8 @@ multi_update::initialize_tables(JOIN *join) NOTES We can update the first table in join on the fly if we know that - a row in this tabel will never be read twice. This is true under - the folloing conditions: + a row in this table will never be read twice. This is true under + the following conditions: - We are doing a table scan and the data is in a separate file (MyISAM) or if we don't update a clustered key. @@ -1082,6 +1086,10 @@ multi_update::initialize_tables(JOIN *join) - We are doing a range scan and we don't update the scan key or the primary key for a clustered table handler. + When checking for above cases we also should take into account that + BEFORE UPDATE trigger potentially may change value of any field in row + being updated. + WARNING This code is a bit dependent of how make_join_readinfo() works. @@ -1100,15 +1108,21 @@ static bool safe_update_on_fly(JOIN_TAB *join_tab, List *fields) return TRUE; // At most one matching row case JT_REF: case JT_REF_OR_NULL: - return !check_if_key_used(table, join_tab->ref.key, *fields); + return !check_if_key_used(table, join_tab->ref.key, *fields) && + !(table->triggers && + table->triggers->has_before_update_triggers()); case JT_ALL: /* If range search on index */ if (join_tab->quick) - return !join_tab->quick->check_if_keys_used(fields); + return !join_tab->quick->check_if_keys_used(fields) && + !(table->triggers && + table->triggers->has_before_update_triggers()); /* If scanning in clustered key */ if ((table->file->table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) && table->s->primary_key < MAX_KEY) - return !check_if_key_used(table, table->s->primary_key, *fields); + return !check_if_key_used(table, table->s->primary_key, *fields) && + !(table->triggers && + table->triggers->has_before_update_triggers()); return TRUE; default: break; // Avoid compler warning @@ -1171,8 +1185,10 @@ bool multi_update::send_data(List ¬_used_values) { table->status|= STATUS_UPDATED; store_record(table,record[1]); - if (fill_record(thd, *fields_for_table[offset], - *values_for_table[offset], 0)) + if (fill_record_n_invoke_before_triggers(thd, *fields_for_table[offset], + *values_for_table[offset], 0, + table->triggers, + TRG_EVENT_UPDATE)) DBUG_RETURN(1); found++; @@ -1208,8 +1224,15 @@ bool multi_update::send_data(List ¬_used_values) DBUG_RETURN(1); } } - else if (!table->file->has_transactions()) - thd->no_trans_update= 1; + else + { + if (!table->file->has_transactions()) + thd->no_trans_update= 1; + if (table->triggers && + table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, + TRG_ACTION_AFTER, TRUE)) + DBUG_RETURN(1); + } } } else @@ -1330,6 +1353,11 @@ int multi_update::do_updates(bool from_send_error) copy_field_ptr++) (*copy_field_ptr->do_copy)(copy_field_ptr); + if (table->triggers && + table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, + TRG_ACTION_BEFORE, TRUE)) + goto err2; + if (compare_record(table, thd->query_id)) { if ((local_error=table->file->update_row(table->record[1], @@ -1339,6 +1367,11 @@ int multi_update::do_updates(bool from_send_error) goto err; } updated++; + + if (table->triggers && + table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, + TRG_ACTION_AFTER, TRUE)) + goto err2; } } @@ -1361,6 +1394,7 @@ err: table->file->print_error(local_error,MYF(0)); } +err2: (void) table->file->ha_rnd_end(); (void) tmp_table->file->ha_rnd_end();