solid c++ by example
DESCRIPTION
Sometimes you see code that is perfectly OK according to the definition of the language, but which is flawed because it breaks too many established idioms and conventions. On the other hand, a solid piece of code is something that looks like it is written by an experienced person who cares about professionalism in programming. A presentation at Norwegian Developer Conference 2010TRANSCRIPT
![Page 1: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/1.jpg)
Solid C++ code by [email protected]
Sometimes you see code that is perfectly OK according to the definition of the language, but which is flawed because it breaks too many established idioms and conventions. On the other hand, a solid piece of code is something that looks like it is written by an experienced person who cares about professionalism in programming.
This will be an interactive discussion about good vs bad C++ code. We will discuss simple C++ idioms and coding conventions, but we will also touch upon best practices when working with C++ in large codebases with lots of developers with mixed skills.
A presentation at Norwegian Developer Conference 2010 Track 7 (1140-1240) June 17, 2010
Disclaimer: there are some issues that we do not address properly here (at least 3). They are left as an exercise for the reader. Email me if you find them, or if you want to know more!
![Page 2: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/2.jpg)
namespace bar { class Foo { int _value; int my_magic(int a, int b); public: Foo(int seed); int calc(int number = 7); int getValue() { return _value; } void print(char* prefix); };}
~/myprog/foo.hpp
![Page 3: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/3.jpg)
namespace bar { class Foo { int _value; int my_magic(int a, int b); public: Foo(int seed); int calc(int number = 7); int getValue() { return _value; } void print(char* prefix); };}
~/myprog/foo.hpp
![Page 4: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/4.jpg)
namespace bar { class Foo { int _value; int my_magic(int a, int b); public: Foo(int seed); int calc(int number = 7); int getValue() { return _value; } void print(char* prefix); };}
~/myprog/foo.hpp
Solid code?
![Page 5: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/5.jpg)
namespace bar { class Foo { int _value; int my_magic(int a, int b); public: Foo(int seed); int calc(int number = 7); int getValue() { return _value; } void print(char* prefix); };}
~/myprog/foo.hpp
![Page 6: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/6.jpg)
namespace bar { class Foo { int _value; int my_magic(int a, int b); public: Foo(int seed); int calc(int number = 7); int getValue() { return _value; } void print(char* prefix); };}
~/myprog/foo.hpp
Bad code?
![Page 7: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/7.jpg)
namespace bar { class Foo { int _value; int my_magic(int a, int b); public: Foo(int seed); int calc(int number = 7); int getValue() { return _value; } void print(char* prefix); };}
~/myprog/foo.hpp
![Page 8: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/8.jpg)
PAL - a Primitive Authentication Library in C++ for educational purposes
http://github.com/olvemaudal/pal
(from the README file)
Here is the main "use story":
As a client, when prompted for ntlm authentication by the server, I want a tool/library that can help me to create the initial ntlm request (type 1 message) that I can send to the server to receive a challenge (type 2 message) that needs to be solved by applying my username and password to create an ntlm response that I can send to the server. (phew...)
Here are some (imaginary) additional requirements:- must be in C or C++, since embeeded- it should be possible and convenient to create a <100kb client using the PAL library- must use C++ (due to PHB decision)- must use nothing but C++ 1998 (due to compiler support, eg tr1 or boost can not be used)- initally the library will only be used to communicate HTTP with a Windows 2003 Server SP2, currently no need to support other servers
![Page 9: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/9.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard15. avoid magic numbers, use explaination variables16. avoid superfluous use of ()17. prefer forward declarations when you can18. do not use explicit on multi argument constructors19. consider explainability, don't do things that needs elaborate explainations20. avoid default arguments (they are often not used anyway)21. do not throw pointers to exceptions (eg, not "throw new ...")22. treat warnings like errors (-Werror) and compile with high warning levels (-Wall -Wextra) 23. consider using -Weffc++ and -pedantic as well24. do not mess with borrowed things25. always consider the sideeffects of what you do
Issues discussed here
![Page 10: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/10.jpg)
![Page 11: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/11.jpg)
![Page 12: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/12.jpg)
ntlm_message.hpp
![Page 13: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/13.jpg)
#include <vector>
namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
![Page 14: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/14.jpg)
#include <vector>
namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
Find 3 issues
![Page 15: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/15.jpg)
#include <vector>
namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
![Page 16: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/16.jpg)
#include <vector>
namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
WTF? This class must have a virtual destructor!
![Page 17: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/17.jpg)
#include <vector>
namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
![Page 18: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/18.jpg)
#include <vector>
namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
missing header guard
![Page 19: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/19.jpg)
#include <vector>
namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
![Page 20: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/20.jpg)
#include <vector>
namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
should include <stdint.h>
![Page 21: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/21.jpg)
#include <vector>
namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
![Page 22: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/22.jpg)
#include <vector>
namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
#ifndef PAL_NTLM_MESSAGE_HPP_INCLUDED#define PAL_NTLM_MESSAGE_HPP_INCLUDED
#endif
![Page 23: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/23.jpg)
#ifndef PAL_NTLM_MESSAGE_HPP_INCLUDED#define PAL_NTLM_MESSAGE_HPP_INCLUDED
#include <vector>
namespace pal { class ntlm_message { public:
virtual std::vector<uint8_t> as_bytes() const = 0; }; }
#endif
![Page 24: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/24.jpg)
virtual ~ntlm_message() {}
#ifndef PAL_NTLM_MESSAGE_HPP_INCLUDED#define PAL_NTLM_MESSAGE_HPP_INCLUDED
#include <vector>
namespace pal { class ntlm_message { public:
virtual std::vector<uint8_t> as_bytes() const = 0; }; }
#endif
![Page 25: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/25.jpg)
#ifndef PAL_NTLM_MESSAGE_HPP_INCLUDED#define PAL_NTLM_MESSAGE_HPP_INCLUDED
#include <vector>
namespace pal { class ntlm_message { public: virtual ~ntlm_message() {} virtual std::vector<uint8_t> as_bytes() const = 0; }; }
#endif
![Page 26: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/26.jpg)
#ifndef PAL_NTLM_MESSAGE_HPP_INCLUDED#define PAL_NTLM_MESSAGE_HPP_INCLUDED
#include <vector>
namespace pal { class ntlm_message { public: virtual ~ntlm_message() {} virtual std::vector<uint8_t> as_bytes() const = 0; }; }
#endif
#include <stdint.h>
![Page 27: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/27.jpg)
#ifndef PAL_NTLM_MESSAGE_HPP_INCLUDED#define PAL_NTLM_MESSAGE_HPP_INCLUDED
#include <vector>
namespace pal { class ntlm_message { public: virtual ~ntlm_message() {} virtual std::vector<uint8_t> as_bytes() const = 0; }; }
#endif
#include <stdint.h>
![Page 28: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/28.jpg)
#ifndef PAL_NTLM_MESSAGE_HPP_INCLUDED#define PAL_NTLM_MESSAGE_HPP_INCLUDED
#include <vector>
namespace pal { class ntlm_message { public: virtual ~ntlm_message() {} virtual std::vector<uint8_t> as_bytes() const = 0; }; }
#endif
#include <stdint.h>
This is Solid C++!
![Page 29: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/29.jpg)
type1_message.hpp
![Page 30: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/30.jpg)
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED#define PAL_TYPE1_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal { class type1_message : public ntlm_message { uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; }
#endif
#include <vector>
![Page 31: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/31.jpg)
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED#define PAL_TYPE1_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal { class type1_message : public ntlm_message { uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; }
#endif
#include <vector>
Find 3 issues
![Page 32: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/32.jpg)
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED#define PAL_TYPE1_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal { class type1_message : public ntlm_message { uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; }
#endif
#include <vector>
![Page 33: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/33.jpg)
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED#define PAL_TYPE1_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal { class type1_message : public ntlm_message { uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; }
#endif
#include <vector>
no need to include <vector> again
![Page 34: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/34.jpg)
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED#define PAL_TYPE1_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal { class type1_message : public ntlm_message { uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; }
#endif
#include <vector>
![Page 35: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/35.jpg)
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED#define PAL_TYPE1_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal { class type1_message : public ntlm_message { uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; }
#endif
#include <vector>
focus on usage; public stuff first, then
private stuff
![Page 36: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/36.jpg)
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED#define PAL_TYPE1_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal { class type1_message : public ntlm_message { uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; }
#endif
#include <vector>
![Page 37: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/37.jpg)
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED#define PAL_TYPE1_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal { class type1_message : public ntlm_message { uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; }
#endif
#include <vector>
single argument constructors should
nearly always have the explicit specifier
![Page 38: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/38.jpg)
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED#define PAL_TYPE1_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <vector>
namespace pal { class type1_message : public ntlm_message { uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; }
#endif
![Page 39: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/39.jpg)
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED#define PAL_TYPE1_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal { class type1_message : public ntlm_message { uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; }
#endif
![Page 40: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/40.jpg)
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED#define PAL_TYPE1_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal { class type1_message : public ntlm_message {
uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; }
#endif
![Page 41: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/41.jpg)
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED#define PAL_TYPE1_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal { class type1_message : public ntlm_message {
uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; }
#endif
private:
![Page 42: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/42.jpg)
public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const;
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED#define PAL_TYPE1_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal { class type1_message : public ntlm_message {
}; }
#endif
private: uint32_t ssp_flags_;
![Page 43: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/43.jpg)
public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const;
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED#define PAL_TYPE1_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal { class type1_message : public ntlm_message {
}; }
#endif
private: uint32_t ssp_flags_;
![Page 44: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/44.jpg)
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED#define PAL_TYPE1_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal { class type1_message : public ntlm_message { public:
virtual std::vector<uint8_t> as_bytes() const; private: uint32_t ssp_flags_; }; }
#endif
type1_message(uint32_t ssp_flags);
![Page 45: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/45.jpg)
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED#define PAL_TYPE1_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal { class type1_message : public ntlm_message { public:
virtual std::vector<uint8_t> as_bytes() const; private: uint32_t ssp_flags_; }; }
#endif
type1_message(uint32_t ssp_flags); explicit
![Page 46: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/46.jpg)
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED#define PAL_TYPE1_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal { class type1_message : public ntlm_message { public: explicit type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; private: uint32_t ssp_flags_; }; }
#endif
![Page 47: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/47.jpg)
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED#define PAL_TYPE1_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal { class type1_message : public ntlm_message { public: explicit type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; private: uint32_t ssp_flags_; }; }
#endif Looks good!
![Page 48: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/48.jpg)
type1_message.cpp
![Page 49: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/49.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
using namespace std;
pal::type1_message::type1_message(uint32_t ssp_flags){ ssp_flags_ = ssp_flags;}
vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message);}
![Page 50: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/50.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
using namespace std;
pal::type1_message::type1_message(uint32_t ssp_flags){ ssp_flags_ = ssp_flags;}
vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message);}
Find at least 3 issues here
![Page 51: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/51.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
using namespace std;
pal::type1_message::type1_message(uint32_t ssp_flags){ ssp_flags_ = ssp_flags;}
vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message);}
![Page 52: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/52.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
using namespace std;
pal::type1_message::type1_message(uint32_t ssp_flags){ ssp_flags_ = ssp_flags;}
vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message);}
focus on readability; importing a namespace might save some keystrokes, but often it does not increase readability
![Page 53: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/53.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
using namespace std;
pal::type1_message::type1_message(uint32_t ssp_flags){ ssp_flags_ = ssp_flags;}
vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message);}
![Page 54: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/54.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
using namespace std;
pal::type1_message::type1_message(uint32_t ssp_flags){ ssp_flags_ = ssp_flags;}
vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message);}
use the initializer list
![Page 55: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/55.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
using namespace std;
pal::type1_message::type1_message(uint32_t ssp_flags){ ssp_flags_ = ssp_flags;}
vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message);}
![Page 56: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/56.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
using namespace std;
pal::type1_message::type1_message(uint32_t ssp_flags){ ssp_flags_ = ssp_flags;}
vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message);}
use std::size_t when appropriate
![Page 57: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/57.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
using namespace std;
pal::type1_message::type1_message(uint32_t ssp_flags){ ssp_flags_ = ssp_flags;}
vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message);}
![Page 58: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/58.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
using namespace std;
pal::type1_message::type1_message(uint32_t ssp_flags){ ssp_flags_ = ssp_flags;}
vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message);}
![Page 59: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/59.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
pal::type1_message::type1_message(uint32_t ssp_flags){ ssp_flags_ = ssp_flags;}
vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message);}
![Page 60: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/60.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
pal::type1_message::type1_message(uint32_t ssp_flags){ ssp_flags_ = ssp_flags;}
vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message);}
![Page 61: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/61.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
pal::type1_message::type1_message(uint32_t ssp_flags){ ssp_flags_ = ssp_flags;}
std::vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message);}
![Page 62: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/62.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
pal::type1_message::type1_message(uint32_t ssp_flags){ ssp_flags_ = ssp_flags;}
std::vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message);}
![Page 63: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/63.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
pal::type1_message::type1_message(uint32_t ssp_flags){ ssp_flags_ = ssp_flags;}
std::vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return std::vector<uint8_t>(message, message + sizeof message);}
![Page 64: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/64.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
pal::type1_message::type1_message(uint32_t ssp_flags){ ssp_flags_ = ssp_flags;}
std::vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return std::vector<uint8_t>(message, message + sizeof message);}
![Page 65: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/65.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
pal::type1_message::type1_message(uint32_t ssp_flags){ ssp_flags_ = ssp_flags;}
std::vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return std::vector<uint8_t>(message, message + sizeof message);}
![Page 66: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/66.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
pal::type1_message::type1_message(uint32_t ssp_flags){ ssp_flags_ = ssp_flags;}
std::vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const std::size_t ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return std::vector<uint8_t>(message, message + sizeof message);}
![Page 67: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/67.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
pal::type1_message::type1_message(uint32_t ssp_flags){ ssp_flags_ = ssp_flags;}
std::vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const std::size_t ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return std::vector<uint8_t>(message, message + sizeof message);}
![Page 68: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/68.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
pal::type1_message::type1_message(uint32_t ssp_flags){ ssp_flags_ = ssp_flags;}
std::vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const std::size_t ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return std::vector<uint8_t>(message, message + sizeof message);}
![Page 69: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/69.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
pal::type1_message::type1_message(uint32_t ssp_flags) : ssp_flags_(ssp_flags){}
std::vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const std::size_t ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return std::vector<uint8_t>(message, message + sizeof message);}
![Page 70: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/70.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
pal::type1_message::type1_message(uint32_t ssp_flags) : ssp_flags_(ssp_flags){}
std::vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const std::size_t ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return std::vector<uint8_t>(message, message + sizeof message);}
![Page 71: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/71.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
pal::type1_message::type1_message(uint32_t ssp_flags) : ssp_flags_(ssp_flags){}
std::vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const std::size_t ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return std::vector<uint8_t>(message, message + sizeof message);}
![Page 72: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/72.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
pal::type1_message::type1_message(uint32_t ssp_flags) : ssp_flags_(ssp_flags){}
std::vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const std::size_t ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return std::vector<uint8_t>(message, message + sizeof message);}
![Page 73: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/73.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */
pal::type1_message::type1_message(uint32_t ssp_flags) : ssp_flags_(ssp_flags){}
std::vector<uint8_t> pal::type1_message::as_bytes() const{ uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const std::size_t ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return std::vector<uint8_t>(message, message + sizeof message);}
This is better
![Page 74: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/74.jpg)
type2_message.hpp
![Page 75: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/75.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
using namespace std;
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; };
}
#endif
![Page 76: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/76.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
using namespace std;
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; };
}
#endif
Find 3 issues
![Page 77: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/77.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
using namespace std;
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; };
}
#endif
![Page 78: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/78.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
using namespace std;
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; };
}
#endif
Ouch, do not import namespaces in
header files!
![Page 79: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/79.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
using namespace std;
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; };
}
#endif
![Page 80: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/80.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
using namespace std;
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; };
}
#endif
pass this vector as const &
![Page 81: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/81.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
using namespace std;
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; };
}
#endif
![Page 82: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/82.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
using namespace std;
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; };
}
#endif
this looks like query methods, they should
probably be const
![Page 83: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/83.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; };
}
#endif
using namespace std;
![Page 84: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/84.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; };
}
#endif
![Page 85: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/85.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; };
}
#endif
![Page 86: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/86.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message( vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; };
}
#endif
![Page 87: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/87.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(std::vector<uint8_t> buffer); virtual std::vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const std::vector<uint8_t> buffer_; };
}
#endif
![Page 88: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/88.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(std::vector<uint8_t> buffer); virtual std::vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const std::vector<uint8_t> buffer_; };
}
#endif
![Page 89: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/89.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(std::vector<uint8_t> buffer); virtual std::vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const std::vector<uint8_t> buffer_; };
}
#endif
![Page 90: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/90.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(std::vector<uint8_t> buffer); virtual std::vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const std::vector<uint8_t> buffer_; };
}
#endif
![Page 91: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/91.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message( std::vector<uint8_t> buffer); virtual std::vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const std::vector<uint8_t> buffer_; };
}
#endif
![Page 92: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/92.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(const std::vector<uint8_t> & buffer); virtual std::vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const std::vector<uint8_t> buffer_; };
}
#endif
![Page 93: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/93.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(const std::vector<uint8_t> & buffer); virtual std::vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const std::vector<uint8_t> buffer_; };
}
#endif
![Page 94: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/94.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(const std::vector<uint8_t> & buffer); virtual std::vector<uint8_t> as_bytes() const; uint32_t ssp_flags() const; uint64_t challenge() const; private: const std::vector<uint8_t> buffer_; };
}
#endif
![Page 95: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/95.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(const std::vector<uint8_t> & buffer); virtual std::vector<uint8_t> as_bytes() const; uint32_t ssp_flags() const; uint64_t challenge() const; private: const std::vector<uint8_t> buffer_; };
}
#endif
![Page 96: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/96.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(const std::vector<uint8_t> & buffer); virtual std::vector<uint8_t> as_bytes() const; uint32_t ssp_flags() const; uint64_t challenge() const; private: const std::vector<uint8_t> buffer_; };
}
#endif
This looks like Solid C++
![Page 97: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/97.jpg)
type2_message.cpp
![Page 98: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/98.jpg)
#include <cstddef>#include <algorithm>#include <stdexcept>
#include "tools.hpp"
#include "type2_message.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 2 Message * * 0 NTLMSSP Signature {'N','T','L','M','S','S','P','\0'} * 8 NTLM Message Type {0x02,0x00,0x00,0x00} * 12 Target Name (security buffer) * 20 Flags uint32 as little endian * 24 Challenge 8 bytes / uint64 as little endian * (32) Context (optional) 8 bytes (2xlong) * (40) Target Information (security buffer) * (48) (start of datablock) * targetname * targetinfo * server (type=0x0100, len, data) * domain (type=0x0200, len, data) * dnsserver (type=0x0300, len, data) * dnsdomain (type=0x0400, len, data) * type5 (type=0x0500, len, data) // unknown role * <terminator> (type=0,len=0) */
... page 1 of 2
...
![Page 99: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/99.jpg)
#include <cstddef>#include <algorithm>#include <stdexcept>
#include "tools.hpp"
#include "type2_message.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 2 Message * * 0 NTLMSSP Signature {'N','T','L','M','S','S','P','\0'} * 8 NTLM Message Type {0x02,0x00,0x00,0x00} * 12 Target Name (security buffer) * 20 Flags uint32 as little endian * 24 Challenge 8 bytes / uint64 as little endian * (32) Context (optional) 8 bytes (2xlong) * (40) Target Information (security buffer) * (48) (start of datablock) * targetname * targetinfo * server (type=0x0100, len, data) * domain (type=0x0200, len, data) * dnsserver (type=0x0300, len, data) * dnsdomain (type=0x0400, len, data) * type5 (type=0x0500, len, data) // unknown role * <terminator> (type=0,len=0) */
... page 1 of 2
...
Find one issue
![Page 100: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/100.jpg)
#include <cstddef>#include <algorithm>#include <stdexcept>
#include "tools.hpp"
#include "type2_message.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 2 Message * * 0 NTLMSSP Signature {'N','T','L','M','S','S','P','\0'} * 8 NTLM Message Type {0x02,0x00,0x00,0x00} * 12 Target Name (security buffer) * 20 Flags uint32 as little endian * 24 Challenge 8 bytes / uint64 as little endian * (32) Context (optional) 8 bytes (2xlong) * (40) Target Information (security buffer) * (48) (start of datablock) * targetname * targetinfo * server (type=0x0100, len, data) * domain (type=0x0200, len, data) * dnsserver (type=0x0300, len, data) * dnsdomain (type=0x0400, len, data) * type5 (type=0x0500, len, data) // unknown role * <terminator> (type=0,len=0) */
... page 1 of 2
...
![Page 101: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/101.jpg)
#include <cstddef>#include <algorithm>#include <stdexcept>
#include "tools.hpp"
#include "type2_message.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 2 Message * * 0 NTLMSSP Signature {'N','T','L','M','S','S','P','\0'} * 8 NTLM Message Type {0x02,0x00,0x00,0x00} * 12 Target Name (security buffer) * 20 Flags uint32 as little endian * 24 Challenge 8 bytes / uint64 as little endian * (32) Context (optional) 8 bytes (2xlong) * (40) Target Information (security buffer) * (48) (start of datablock) * targetname * targetinfo * server (type=0x0100, len, data) * domain (type=0x0200, len, data) * dnsserver (type=0x0300, len, data) * dnsdomain (type=0x0400, len, data) * type5 (type=0x0500, len, data) // unknown role * <terminator> (type=0,len=0) */
... page 1 of 2
...
this is not a good way to order the include files
![Page 102: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/102.jpg)
#include <cstddef>#include <algorithm>#include <stdexcept>
#include "tools.hpp"
#include "type2_message.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 2 Message * * 0 NTLMSSP Signature {'N','T','L','M','S','S','P','\0'} * 8 NTLM Message Type {0x02,0x00,0x00,0x00} * 12 Target Name (security buffer) * 20 Flags uint32 as little endian * 24 Challenge 8 bytes / uint64 as little endian * (32) Context (optional) 8 bytes (2xlong) * (40) Target Information (security buffer) * (48) (start of datablock) * targetname * targetinfo * server (type=0x0100, len, data) * domain (type=0x0200, len, data) * dnsserver (type=0x0300, len, data) * dnsdomain (type=0x0400, len, data) * type5 (type=0x0500, len, data) // unknown role * <terminator> (type=0,len=0) */
... page 1 of 2
...
![Page 103: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/103.jpg)
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 2 Message * * 0 NTLMSSP Signature {'N','T','L','M','S','S','P','\0'} * 8 NTLM Message Type {0x02,0x00,0x00,0x00} * 12 Target Name (security buffer) * 20 Flags uint32 as little endian * 24 Challenge 8 bytes / uint64 as little endian * (32) Context (optional) 8 bytes (2xlong) * (40) Target Information (security buffer) * (48) (start of datablock) * targetname * targetinfo * server (type=0x0100, len, data) * domain (type=0x0200, len, data) * dnsserver (type=0x0300, len, data) * dnsdomain (type=0x0400, len, data) * type5 (type=0x0500, len, data) // unknown role * <terminator> (type=0,len=0) */
... page 1 of 2
...
#include "type2_message.hpp"
#include "tools.hpp"
#include <cstddef>#include <algorithm>#include <stdexcept>
![Page 104: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/104.jpg)
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 2 Message * * 0 NTLMSSP Signature {'N','T','L','M','S','S','P','\0'} * 8 NTLM Message Type {0x02,0x00,0x00,0x00} * 12 Target Name (security buffer) * 20 Flags uint32 as little endian * 24 Challenge 8 bytes / uint64 as little endian * (32) Context (optional) 8 bytes (2xlong) * (40) Target Information (security buffer) * (48) (start of datablock) * targetname * targetinfo * server (type=0x0100, len, data) * domain (type=0x0200, len, data) * dnsserver (type=0x0300, len, data) * dnsdomain (type=0x0400, len, data) * type5 (type=0x0500, len, data) // unknown role * <terminator> (type=0,len=0) */
... page 1 of 2
...
#include "type2_message.hpp"
#include "tools.hpp"
#include <cstddef>#include <algorithm>#include <stdexcept>
![Page 105: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/105.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','\0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix");}
uint32_t pal::type2_message::ssp_flags() const{ return pal::read_uint32_from_little_endian(&buffer_[20]);}
uint64_t pal::type2_message::challenge() const{ return pal::read_uint64_from_little_endian(&buffer_[24]);}
std::vector<uint8_t> pal::type2_message::as_bytes() const{ return (buffer_);}
... page 2 of 2
![Page 106: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/106.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','\0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix");}
uint32_t pal::type2_message::ssp_flags() const{ return pal::read_uint32_from_little_endian(&buffer_[20]);}
uint64_t pal::type2_message::challenge() const{ return pal::read_uint64_from_little_endian(&buffer_[24]);}
std::vector<uint8_t> pal::type2_message::as_bytes() const{ return (buffer_);}
... page 2 of 2
Any issues here?
![Page 107: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/107.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','\0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix");}
uint32_t pal::type2_message::ssp_flags() const{ return pal::read_uint32_from_little_endian(&buffer_[20]);}
uint64_t pal::type2_message::challenge() const{ return pal::read_uint64_from_little_endian(&buffer_[24]);}
std::vector<uint8_t> pal::type2_message::as_bytes() const{ return (buffer_);}
... page 2 of 2
![Page 108: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/108.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','\0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix");}
uint32_t pal::type2_message::ssp_flags() const{ return pal::read_uint32_from_little_endian(&buffer_[20]);}
uint64_t pal::type2_message::challenge() const{ return pal::read_uint64_from_little_endian(&buffer_[24]);}
std::vector<uint8_t> pal::type2_message::as_bytes() const{ return (buffer_);}
... page 2 of 2 magic numbers
![Page 109: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/109.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','\0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix");}
uint32_t pal::type2_message::ssp_flags() const{ return pal::read_uint32_from_little_endian(&buffer_[20]);}
uint64_t pal::type2_message::challenge() const{ return pal::read_uint64_from_little_endian(&buffer_[24]);}
std::vector<uint8_t> pal::type2_message::as_bytes() const{ return (buffer_);}
... page 2 of 2
![Page 110: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/110.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','\0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix");}
uint32_t pal::type2_message::ssp_flags() const{ return pal::read_uint32_from_little_endian(&buffer_[20]);}
uint64_t pal::type2_message::challenge() const{ return pal::read_uint64_from_little_endian(&buffer_[24]);}
std::vector<uint8_t> pal::type2_message::as_bytes() const{ return (buffer_);}
... page 2 of 2
superfluous use of ()
![Page 111: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/111.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','\0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix");}
uint32_t pal::type2_message::ssp_flags() const{ return pal::read_uint32_from_little_endian(&buffer_[20]);}
uint64_t pal::type2_message::challenge() const{ return pal::read_uint64_from_little_endian(&buffer_[24]);}
std::vector<uint8_t> pal::type2_message::as_bytes() const{ return (buffer_);}
... page 2 of 2
superfluous use of ()
![Page 112: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/112.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','\0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof((prefix)), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix");}
uint32_t pal::type2_message::ssp_flags() const{ return pal::read_uint32_from_little_endian(&buffer_[20]);}
uint64_t pal::type2_message::challenge() const{ return pal::read_uint64_from_little_endian(&buffer_[24]);}
std::vector<uint8_t> pal::type2_message::as_bytes() const{ return (((buffer_)));}
... page 2 of 2
so you really like () do you? Why not add a few more?
![Page 113: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/113.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = (32); if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','\0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof((prefix)), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix");}
uint32_t pal::type2_message::ssp_flags() const{ return pal::read_uint32_from_little_endian(&buffer_[20]);}
uint64_t pal::type2_message::challenge() const{ return pal::read_uint64_from_little_endian(&buffer_[24]);}
std::vector<uint8_t> pal::type2_message::as_bytes() const{ return (((buffer_)));}
... page 2 of 2
so you really like () do you? Why not add a few more?
![Page 114: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/114.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','\0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix");}
uint32_t pal::type2_message::ssp_flags() const{ return pal::read_uint32_from_little_endian(&buffer_[20]);}
uint64_t pal::type2_message::challenge() const{ return pal::read_uint64_from_little_endian(&buffer_[24]);}
std::vector<uint8_t> pal::type2_message::as_bytes() const{ return (buffer_);}
... page 2 of 2
![Page 115: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/115.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','\0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix");}
uint32_t pal::type2_message::ssp_flags() const{
return pal::read_uint32_from_little_endian(&buffer_[20]);}
uint64_t pal::type2_message::challenge() const{ return pal::read_uint64_from_little_endian(&buffer_[24]);}
std::vector<uint8_t> pal::type2_message::as_bytes() const{ return (buffer_);}
... page 2 of 2
![Page 116: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/116.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','\0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix");}
uint32_t pal::type2_message::ssp_flags() const{
return pal::read_uint32_from_little_endian(&buffer_[20]);}
uint64_t pal::type2_message::challenge() const{
return pal::read_uint64_from_little_endian(&buffer_[24]);}
std::vector<uint8_t> pal::type2_message::as_bytes() const{ return (buffer_);}
... page 2 of 2
![Page 117: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/117.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','\0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix");}
uint32_t pal::type2_message::ssp_flags() const{
return pal::read_uint32_from_little_endian(&buffer_[20]);}
uint64_t pal::type2_message::challenge() const{
return pal::read_uint64_from_little_endian(&buffer_[24]);}
std::vector<uint8_t> pal::type2_message::as_bytes() const{ return (buffer_);}
... page 2 of 2
![Page 118: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/118.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','\0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix");}
uint32_t pal::type2_message::ssp_flags() const{ const std::size_t ssp_flags_offset = 20; return pal::read_uint32_from_little_endian(&buffer_[20]);}
uint64_t pal::type2_message::challenge() const{ const std::size_t challenge_offset = 24; return pal::read_uint64_from_little_endian(&buffer_[24]);}
std::vector<uint8_t> pal::type2_message::as_bytes() const{ return (buffer_);}
... page 2 of 2
![Page 119: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/119.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','\0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix");}
uint32_t pal::type2_message::ssp_flags() const{ const std::size_t ssp_flags_offset = 20; return pal::read_uint32_from_little_endian(&buffer_[20]);}
uint64_t pal::type2_message::challenge() const{ const std::size_t challenge_offset = 24; return pal::read_uint64_from_little_endian(&buffer_[24]);}
std::vector<uint8_t> pal::type2_message::as_bytes() const{ return (buffer_);}
... page 2 of 2
![Page 120: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/120.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','\0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix");}
uint32_t pal::type2_message::ssp_flags() const{ const std::size_t ssp_flags_offset = 20; return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]);}
uint64_t pal::type2_message::challenge() const{ const std::size_t challenge_offset = 24; return pal::read_uint64_from_little_endian(&buffer_[24]);}
std::vector<uint8_t> pal::type2_message::as_bytes() const{ return (buffer_);}
... page 2 of 2
![Page 121: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/121.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','\0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix");}
uint32_t pal::type2_message::ssp_flags() const{ const std::size_t ssp_flags_offset = 20; return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]);}
uint64_t pal::type2_message::challenge() const{ const std::size_t challenge_offset = 24; return pal::read_uint64_from_little_endian(&buffer_[challenge_offset]);}
std::vector<uint8_t> pal::type2_message::as_bytes() const{ return (buffer_);}
... page 2 of 2
![Page 122: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/122.jpg)
( )
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','\0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof prefix , buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix");}
uint32_t pal::type2_message::ssp_flags() const{ const std::size_t ssp_flags_offset = 20; return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]);}
uint64_t pal::type2_message::challenge() const{ const std::size_t challenge_offset = 24; return pal::read_uint64_from_little_endian(&buffer_[challenge_offset]);}
std::vector<uint8_t> pal::type2_message::as_bytes() const{ return buffer_ ;}
... page 2 of 2
( )
![Page 123: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/123.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','\0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof prefix , buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix");}
uint32_t pal::type2_message::ssp_flags() const{ const std::size_t ssp_flags_offset = 20; return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]);}
uint64_t pal::type2_message::challenge() const{ const std::size_t challenge_offset = 24; return pal::read_uint64_from_little_endian(&buffer_[challenge_offset]);}
std::vector<uint8_t> pal::type2_message::as_bytes() const{ return buffer_ ;}
... page 2 of 2
( )
![Page 124: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/124.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','\0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof prefix , buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix");}
uint32_t pal::type2_message::ssp_flags() const{ const std::size_t ssp_flags_offset = 20; return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]);}
uint64_t pal::type2_message::challenge() const{ const std::size_t challenge_offset = 24; return pal::read_uint64_from_little_endian(&buffer_[challenge_offset]);}
std::vector<uint8_t> pal::type2_message::as_bytes() const{ return buffer_ ;}
... page 2 of 2
( )
![Page 125: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/125.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','\0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof prefix , buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix");}
uint32_t pal::type2_message::ssp_flags() const{ const std::size_t ssp_flags_offset = 20; return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]);}
uint64_t pal::type2_message::challenge() const{ const std::size_t challenge_offset = 24; return pal::read_uint64_from_little_endian(&buffer_[challenge_offset]);}
std::vector<uint8_t> pal::type2_message::as_bytes() const{ return buffer_ ;}
... page 2 of 2
![Page 126: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/126.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','\0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof prefix, buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix");}
uint32_t pal::type2_message::ssp_flags() const{ const std::size_t ssp_flags_offset = 20; return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]);}
uint64_t pal::type2_message::challenge() const{ const std::size_t challenge_offset = 24; return pal::read_uint64_from_little_endian(&buffer_[challenge_offset]);}
std::vector<uint8_t> pal::type2_message::as_bytes() const{ return buffer_;}
... page 2 of 2
![Page 127: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/127.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','\0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof prefix, buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix");}
uint32_t pal::type2_message::ssp_flags() const{ const std::size_t ssp_flags_offset = 20; return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]);}
uint64_t pal::type2_message::challenge() const{ const std::size_t challenge_offset = 24; return pal::read_uint64_from_little_endian(&buffer_[challenge_offset]);}
std::vector<uint8_t> pal::type2_message::as_bytes() const{ return buffer_;}
... page 2 of 2
![Page 128: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/128.jpg)
type3_message.hpp
![Page 129: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/129.jpg)
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED#define PAL_TYPE3_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <string>#include <iostream>
namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; }
#endif
![Page 130: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/130.jpg)
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED#define PAL_TYPE3_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <string>#include <iostream>
namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; }
#endif
Find 3 issues
![Page 131: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/131.jpg)
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED#define PAL_TYPE3_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <string>#include <iostream>
namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; }
#endif
![Page 132: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/132.jpg)
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED#define PAL_TYPE3_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <string>#include <iostream>
namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; }
#endif
include <iosfwd> instead
![Page 133: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/133.jpg)
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED#define PAL_TYPE3_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <string>#include <iostream>
namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; }
#endif
![Page 134: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/134.jpg)
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED#define PAL_TYPE3_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <string>#include <iostream>
namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; }
#endif
this default argument is probably not needed
![Page 135: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/135.jpg)
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED#define PAL_TYPE3_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <string>#include <iostream>
namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; }
#endif
![Page 136: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/136.jpg)
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED#define PAL_TYPE3_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <string>#include <iostream>
namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; }
#endif
useless explicit specifier
![Page 137: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/137.jpg)
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED#define PAL_TYPE3_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <string>#include <iostream>
namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; }
#endif
![Page 138: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/138.jpg)
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED#define PAL_TYPE3_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <string>#include <iostream>
namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; }
#endif
![Page 139: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/139.jpg)
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED#define PAL_TYPE3_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <string>#include <iosfwd>
namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; }
#endif
![Page 140: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/140.jpg)
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED#define PAL_TYPE3_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <string>#include <iosfwd>
namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; }
#endif
![Page 141: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/141.jpg)
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED#define PAL_TYPE3_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <string>#include <iosfwd>
namespace pal { class type3_message : public ntlm_message { public: type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags ); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; }
#endif
= 0x202
explicit
![Page 142: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/142.jpg)
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED#define PAL_TYPE3_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <string>#include <iosfwd>
namespace pal { class type3_message : public ntlm_message { public: type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags ); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; }
#endif
= 0x202
![Page 143: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/143.jpg)
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED#define PAL_TYPE3_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <string>#include <iosfwd>
namespace pal { class type3_message : public ntlm_message { public: type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags ); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; }
#endif
= 0x202
![Page 144: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/144.jpg)
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED#define PAL_TYPE3_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <string>#include <iosfwd>
namespace pal { class type3_message : public ntlm_message { public: type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags ); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; }
#endif
![Page 145: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/145.jpg)
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED#define PAL_TYPE3_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <string>#include <iosfwd>
namespace pal { class type3_message : public ntlm_message { public: type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; }
#endif
![Page 146: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/146.jpg)
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED#define PAL_TYPE3_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <string>#include <iosfwd>
namespace pal { class type3_message : public ntlm_message { public: type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; }
#endif
![Page 147: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/147.jpg)
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED#define PAL_TYPE3_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <string>#include <iosfwd>
namespace pal { class type3_message : public ntlm_message { public: type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; }
#endif
Not too bad!
![Page 148: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/148.jpg)
type3_message.cpp
![Page 149: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/149.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
![Page 150: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/150.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
Find 3 issues
![Page 151: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/151.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
![Page 152: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/152.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
WTF?
![Page 153: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/153.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
![Page 154: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/154.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
Does not match initialization order...
![Page 155: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/155.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
![Page 156: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/156.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
... but this indicates a deeper problem, the user is not compiling with -Wall and -Wextra, or even worse... they
do not care about warnings!
![Page 157: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/157.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
![Page 158: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/158.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
It's often a good idea to explicitly initialize all object members. Consider the -Weffc++ flag
![Page 159: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/159.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
![Page 160: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/160.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
![Page 161: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/161.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw std::invalid_argument("invalid size of nt_response");}
...
...
![Page 162: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/162.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw std::invalid_argument("invalid size of nt_response");}
...
...
![Page 163: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/163.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), session_key_(session_key_size), ssp_flags_(ssp_flags){ if (lm_response_.size() != lm_response_size) throw std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw std::invalid_argument("invalid size of nt_response");}
...
...
![Page 164: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/164.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response),
user_(user),
session_key_(session_key_size), ssp_flags_(ssp_flags){ if (lm_response_.size() != lm_response_size) throw std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw std::invalid_argument("invalid size of nt_response");}
...
...
![Page 165: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/165.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), domain_(), user_(user), workstation_(), session_key_(session_key_size), ssp_flags_(ssp_flags){ if (lm_response_.size() != lm_response_size) throw std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw std::invalid_argument("invalid size of nt_response");}
...
...
![Page 166: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/166.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), domain_(), user_(user), workstation_(), session_key_(session_key_size), ssp_flags_(ssp_flags){ if (lm_response_.size() != lm_response_size) throw std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw std::invalid_argument("invalid size of nt_response");}
...
...
![Page 167: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/167.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), domain_(), user_(user), workstation_(), session_key_(session_key_size), ssp_flags_(ssp_flags){ if (lm_response_.size() != lm_response_size) throw std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw std::invalid_argument("invalid size of nt_response");}
...
...
Much better!
![Page 168: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/168.jpg)
void pal::type3_message::debug_print(std::ostream & out) const{ out << "### type3_message:" << '\n' << pal::as_hex_dump(as_bytes()) << "lm_response = " << pal::as_hex_string(lm_response_) << "\nnt_response = " << pal::as_hex_string(nt_response_) << "\ndomain = " << domain_ << "\nuser = " << user_ << "\nworkstation = " << workstation_ << "\nsession_key = " << pal::as_hex_string(session_key_) << std::hex << std::setw(8) << std::setfill('0') << "\nssp_flags = " << ssp_flags_;}
...
...
![Page 169: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/169.jpg)
void pal::type3_message::debug_print(std::ostream & out) const{ out << "### type3_message:" << '\n' << pal::as_hex_dump(as_bytes()) << "lm_response = " << pal::as_hex_string(lm_response_) << "\nnt_response = " << pal::as_hex_string(nt_response_) << "\ndomain = " << domain_ << "\nuser = " << user_ << "\nworkstation = " << workstation_ << "\nsession_key = " << pal::as_hex_string(session_key_) << std::hex << std::setw(8) << std::setfill('0') << "\nssp_flags = " << ssp_flags_;}
...
...
Any issues here?
![Page 170: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/170.jpg)
void pal::type3_message::debug_print(std::ostream & out) const{ out << "### type3_message:" << '\n' << pal::as_hex_dump(as_bytes()) << "lm_response = " << pal::as_hex_string(lm_response_) << "\nnt_response = " << pal::as_hex_string(nt_response_) << "\ndomain = " << domain_ << "\nuser = " << user_ << "\nworkstation = " << workstation_ << "\nsession_key = " << pal::as_hex_string(session_key_) << std::hex << std::setw(8) << std::setfill('0') << "\nssp_flags = " << ssp_flags_;}
...
...
![Page 171: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/171.jpg)
void pal::type3_message::debug_print(std::ostream & out) const{ out << "### type3_message:" << '\n' << pal::as_hex_dump(as_bytes()) << "lm_response = " << pal::as_hex_string(lm_response_) << "\nnt_response = " << pal::as_hex_string(nt_response_) << "\ndomain = " << domain_ << "\nuser = " << user_ << "\nworkstation = " << workstation_ << "\nsession_key = " << pal::as_hex_string(session_key_) << std::hex << std::setw(8) << std::setfill('0') << "\nssp_flags = " << ssp_flags_;}
...
...
DO NOT MESS WITH BORROWED THINGS!
![Page 172: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/172.jpg)
void pal::type3_message::debug_print(std::ostream & out) const{ out << "### type3_message:" << '\n' << pal::as_hex_dump(as_bytes()) << "lm_response = " << pal::as_hex_string(lm_response_) << "\nnt_response = " << pal::as_hex_string(nt_response_) << "\ndomain = " << domain_ << "\nuser = " << user_ << "\nworkstation = " << workstation_ << "\nsession_key = " << pal::as_hex_string(session_key_) << std::hex << std::setw(8) << std::setfill('0') << "\nssp_flags = " << ssp_flags_;}
...
...
![Page 173: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/173.jpg)
void pal::type3_message::debug_print(std::ostream & out) const{ out << "### type3_message:" << '\n' << pal::as_hex_dump(as_bytes()) << "lm_response = " << pal::as_hex_string(lm_response_) << "\nnt_response = " << pal::as_hex_string(nt_response_) << "\ndomain = " << domain_ << "\nuser = " << user_ << "\nworkstation = " << workstation_ << "\nsession_key = " << pal::as_hex_string(session_key_) << std::hex << std::setw(8) << std::setfill('0') << "\nssp_flags = " << ssp_flags_;}
...
...
No easy way to fix this! Probably better to build into a local stringstream and return it.
![Page 174: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/174.jpg)
void pal::type3_message::debug_print(std::ostream & out) const{ out << "### type3_message:" << '\n' << pal::as_hex_dump(as_bytes()) << "lm_response = " << pal::as_hex_string(lm_response_) << "\nnt_response = " << pal::as_hex_string(nt_response_) << "\ndomain = " << domain_ << "\nuser = " << user_ << "\nworkstation = " << workstation_ << "\nsession_key = " << pal::as_hex_string(session_key_) << std::hex << std::setw(8) << std::setfill('0') << "\nssp_flags = " << ssp_flags_;}
...
...
![Page 175: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/175.jpg)
std::string pal::type3_message::debug_print() const{ std::ostringstream buf; buf << "### type3_message:" << '\n' << pal::as_hex_dump(as_bytes()) << "lm_response = " << pal::as_hex_string(lm_response_) << "\nnt_response = " << pal::as_hex_string(nt_response_) << "\ndomain = " << domain_ << "\nuser = " << user_ << "\nworkstation = " << workstation_ << "\nsession_key = " << pal::as_hex_string(session_key_) << std::hex << std::setw(8) << std::setfill('0') << "\nssp_flags = " << ssp_flags_; return buf.str();}
...
...
![Page 176: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/176.jpg)
std::string pal::type3_message::debug_print() const{ std::ostringstream buf; buf << "### type3_message:" << '\n' << pal::as_hex_dump(as_bytes()) << "lm_response = " << pal::as_hex_string(lm_response_) << "\nnt_response = " << pal::as_hex_string(nt_response_) << "\ndomain = " << domain_ << "\nuser = " << user_ << "\nworkstation = " << workstation_ << "\nsession_key = " << pal::as_hex_string(session_key_) << std::hex << std::setw(8) << std::setfill('0') << "\nssp_flags = " << ssp_flags_; return buf.str();}
...
...
![Page 177: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/177.jpg)
std::string pal::type3_message::debug_print() const{ std::ostringstream buf; buf << "### type3_message:" << '\n' << pal::as_hex_dump(as_bytes()) << "lm_response = " << pal::as_hex_string(lm_response_) << "\nnt_response = " << pal::as_hex_string(nt_response_) << "\ndomain = " << domain_ << "\nuser = " << user_ << "\nworkstation = " << workstation_ << "\nsession_key = " << pal::as_hex_string(session_key_) << std::hex << std::setw(8) << std::setfill('0') << "\nssp_flags = " << ssp_flags_; return buf.str();}
...
...
Big improvement!
![Page 178: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/178.jpg)
Issues discussed here
![Page 179: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/179.jpg)
1. base classes should have virtual destructors
Issues discussed here
![Page 180: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/180.jpg)
1. base classes should have virtual destructors2. header files should have header guards
Issues discussed here
![Page 181: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/181.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files
Issues discussed here
![Page 182: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/182.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration
Issues discussed here
![Page 183: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/183.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit
Issues discussed here
![Page 184: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/184.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff
Issues discussed here
![Page 185: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/185.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it
Issues discussed here
![Page 186: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/186.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea
Issues discussed here
![Page 187: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/187.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file
Issues discussed here
![Page 188: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/188.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list
Issues discussed here
![Page 189: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/189.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets
Issues discussed here
![Page 190: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/190.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy
Issues discussed here
![Page 191: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/191.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const
Issues discussed here
![Page 192: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/192.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard
Issues discussed here
![Page 193: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/193.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard15. avoid magic numbers, use explaination variables
Issues discussed here
![Page 194: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/194.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard15. avoid magic numbers, use explaination variables16. avoid superfluous use of ()
Issues discussed here
![Page 195: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/195.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard15. avoid magic numbers, use explaination variables16. avoid superfluous use of ()17. prefer forward declarations when you can
Issues discussed here
![Page 196: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/196.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard15. avoid magic numbers, use explaination variables16. avoid superfluous use of ()17. prefer forward declarations when you can18. do not use explicit on multi argument constructors
Issues discussed here
![Page 197: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/197.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard15. avoid magic numbers, use explaination variables16. avoid superfluous use of ()17. prefer forward declarations when you can18. do not use explicit on multi argument constructors19. consider explainability, don't do things that needs elaborate explainations
Issues discussed here
![Page 198: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/198.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard15. avoid magic numbers, use explaination variables16. avoid superfluous use of ()17. prefer forward declarations when you can18. do not use explicit on multi argument constructors19. consider explainability, don't do things that needs elaborate explainations20. avoid default arguments (they are often not used anyway)
Issues discussed here
![Page 199: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/199.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard15. avoid magic numbers, use explaination variables16. avoid superfluous use of ()17. prefer forward declarations when you can18. do not use explicit on multi argument constructors19. consider explainability, don't do things that needs elaborate explainations20. avoid default arguments (they are often not used anyway)21. do not throw pointers to exceptions (eg, not "throw new ...")
Issues discussed here
![Page 200: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/200.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard15. avoid magic numbers, use explaination variables16. avoid superfluous use of ()17. prefer forward declarations when you can18. do not use explicit on multi argument constructors19. consider explainability, don't do things that needs elaborate explainations20. avoid default arguments (they are often not used anyway)21. do not throw pointers to exceptions (eg, not "throw new ...")22. treat warnings like errors (-Werror) and compile with high warning levels (-Wall -Wextra)
Issues discussed here
![Page 201: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/201.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard15. avoid magic numbers, use explaination variables16. avoid superfluous use of ()17. prefer forward declarations when you can18. do not use explicit on multi argument constructors19. consider explainability, don't do things that needs elaborate explainations20. avoid default arguments (they are often not used anyway)21. do not throw pointers to exceptions (eg, not "throw new ...")22. treat warnings like errors (-Werror) and compile with high warning levels (-Wall -Wextra) 23. consider using -Weffc++ and -pedantic as well
Issues discussed here
![Page 202: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/202.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard15. avoid magic numbers, use explaination variables16. avoid superfluous use of ()17. prefer forward declarations when you can18. do not use explicit on multi argument constructors19. consider explainability, don't do things that needs elaborate explainations20. avoid default arguments (they are often not used anyway)21. do not throw pointers to exceptions (eg, not "throw new ...")22. treat warnings like errors (-Werror) and compile with high warning levels (-Wall -Wextra) 23. consider using -Weffc++ and -pedantic as well24. do not mess with borrowed things
Issues discussed here
![Page 203: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/203.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard15. avoid magic numbers, use explaination variables16. avoid superfluous use of ()17. prefer forward declarations when you can18. do not use explicit on multi argument constructors19. consider explainability, don't do things that needs elaborate explainations20. avoid default arguments (they are often not used anyway)21. do not throw pointers to exceptions (eg, not "throw new ...")22. treat warnings like errors (-Werror) and compile with high warning levels (-Wall -Wextra) 23. consider using -Weffc++ and -pedantic as well24. do not mess with borrowed things25. always consider the sideeffects of what you do
Issues discussed here
![Page 204: Solid C++ by Example](https://reader035.vdocument.in/reader035/viewer/2022081717/554f5ce1b4c905b9508b54d3/html5/thumbnails/204.jpg)
!