Permalink
Browse files

Fix flag handling: 3-byte flag sets are padded to 4 bytes in non-16-b…

…it installers.
  • Loading branch information...
1 parent 70c08b5 commit 273f095f7bdf284a96f541812db0d7a6fc74601a @dscharrer committed Mar 17, 2012
Showing with 63 additions and 35 deletions.
  1. +2 −2 src/setup/data.cpp
  2. +4 −2 src/setup/directory.cpp
  3. +3 −11 src/setup/file.cpp
  4. +2 −2 src/setup/header.cpp
  5. +2 −2 src/setup/icon.cpp
  6. +6 −2 src/setup/ini.cpp
  7. +2 −2 src/setup/registry.cpp
  8. +2 −2 src/setup/run.cpp
  9. +40 −10 src/util/storedenum.hpp
View
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Daniel Scharrer
+ * Copyright (C) 2011-2012 Daniel Scharrer
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the author(s) be held liable for any damages
@@ -95,7 +95,7 @@ void data_entry::load(std::istream & is, const version & version) {
options = 0;
- stored_flag_reader<flags> flags(is);
+ stored_flag_reader<flags> flags(is, version.bits);
flags.add(VersionInfoValid);
flags.add(VersionInfoNotValid);
View
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Daniel Scharrer
+ * Copyright (C) 2011-2012 Daniel Scharrer
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the author(s) be held liable for any damages
@@ -77,8 +77,10 @@ void directory_entry::load(std::istream & is, const version & version) {
if(version >= INNO_VERSION(5, 2, 0)) {
options = stored_flags<stored_inno_directory_options_1>(is).get();
- } else {
+ } else if(version.bits != 16) {
options = stored_flags<stored_inno_directory_options_0>(is).get();
+ } else {
+ options = stored_flags<stored_inno_directory_options_0, 16>(is).get();
}
}
View
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Daniel Scharrer
+ * Copyright (C) 2011-2012 Daniel Scharrer
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the author(s) be held liable for any damages
@@ -114,7 +114,7 @@ void file_entry::load(std::istream & is, const version & version) {
permission = -1;
}
- stored_flag_reader<flags> flags(is);
+ stored_flag_reader<flags> flags(is, version.bits);
flags.add(ConfirmOverwrite);
flags.add(NeverUninstall);
@@ -184,15 +184,7 @@ void file_entry::load(std::istream & is, const version & version) {
flags.add(GacInstall);
}
- options = flags;
-
- if(version >= INNO_VERSION(3, 0, 5) && version < INNO_VERSION(5, 0, 3)) {
- // TODO find out where this byte comes from
- int byte = is.get();
- if(byte) {
- log_warning << "[file] unknown byte: " << byte;
- }
- }
+ options |= flags;
if(version.bits == 16 || version >= INNO_VERSION(5, 0, 0)) {
type = stored_enum<stored_file_type_0>(is).get();
View
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Daniel Scharrer
+ * Copyright (C) 2011-2012 Daniel Scharrer
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the author(s) be held liable for any damages
@@ -396,7 +396,7 @@ void header::load(std::istream & is, const version & version) {
}
- stored_flag_reader<flags> flags(is);
+ stored_flag_reader<flags> flags(is, version.bits);
flags.add(DisableStartupPrompt);
if(version < INNO_VERSION(5, 3, 10)) {
View
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Daniel Scharrer
+ * Copyright (C) 2011-2012 Daniel Scharrer
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the author(s) be held liable for any damages
@@ -74,7 +74,7 @@ void icon_entry::load(std::istream & is, const version & version) {
hotkey = 0;
}
- stored_flag_reader<flags> flags(is);
+ stored_flag_reader<flags> flags(is, version.bits);
flags.add(NeverUninstall);
if(version >= INNO_VERSION(1, 3, 21)) {
View
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Daniel Scharrer
+ * Copyright (C) 2011-2012 Daniel Scharrer
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the author(s) be held liable for any damages
@@ -58,7 +58,11 @@ void ini_entry::load(std::istream & is, const version & version) {
load_version_data(is, version);
- options = stored_flags<stored_ini_flags>(is).get();
+ if(version.bits != 16) {
+ options = stored_flags<stored_ini_flags>(is).get();
+ } else {
+ options = stored_flags<stored_ini_flags, 16>(is).get();
+ }
}
} // namespace setup
View
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Daniel Scharrer
+ * Copyright (C) 2011-2012 Daniel Scharrer
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the author(s) be held liable for any damages
@@ -102,7 +102,7 @@ void registry_entry::load(std::istream & is, const version & version) {
type = stored_enum<stored_registry_entry_type_0>(is).get();
}
- stored_flag_reader<flags> flags(is);
+ stored_flag_reader<flags> flags(is, version.bits);
if(version.bits != 16) {
flags.add(CreateValueIfDoesntExist);
View
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Daniel Scharrer
+ * Copyright (C) 2011-2012 Daniel Scharrer
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the author(s) be held liable for any damages
@@ -78,7 +78,7 @@ void run_entry::load(std::istream & is, const version & version) {
wait = stored_enum<stored_run_wait_condition>(is).get();
- stored_flag_reader<flags> flags(is);
+ stored_flag_reader<flags> flags(is, version.bits);
flags.add(ShellExec);
if(version >= INNO_VERSION(1, 3, 21)) {
View
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Daniel Scharrer
+ * Copyright (C) 2011-2012 Daniel Scharrer
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the author(s) be held liable for any damages
@@ -84,7 +84,11 @@ struct stored_enum {
};
-template <size_t Bits>
+/*!
+ * Load a packed bitfield: 1 byte for every 8 bits
+ * The only exception is that 3-byte bitfields are padded to 4 bytes for non-16-bit builds.
+ */
+template <size_t Bits, size_t PadBits = 32>
class stored_bitfield {
typedef uint8_t base_type;
@@ -102,6 +106,10 @@ class stored_bitfield {
for(size_t i = 0; i < count; i++) {
bits[i] = load_number<base_type>(is);
}
+ if(count == 3 && PadBits == 32) {
+ // 3-byte sets are padded to 4 bytes
+ (void)load_number<base_type>(is);
+ }
}
inline uint64_t lower_bits() const {
@@ -140,16 +148,21 @@ class stored_bitfield {
};
-template <class Mapping>
-class stored_flags : private stored_bitfield<Mapping::count> {
+/*!
+ * Load a flag set where the possible flags are known at compile-time.
+ * Inno Setup stores flag sets as packed bitfields: 1 byte for every 8 flags
+ * The only exception is that 3-byte bitfields are padded to 4 bytes for non-16-bit builds.
+ */
+template <class Mapping, size_t PadBits = 32>
+class stored_flags : private stored_bitfield<Mapping::count, PadBits> {
public:
typedef Mapping mapping_type;
typedef typename Mapping::enum_type enum_type;
typedef flags<enum_type> flag_type;
- inline stored_flags(std::istream & is) : stored_bitfield<Mapping::count>(is) { }
+ inline stored_flags(std::istream & is) : stored_bitfield<Mapping::count, PadBits>(is) { }
flag_type get() {
@@ -173,6 +186,11 @@ class stored_flags : private stored_bitfield<Mapping::count> {
};
+/*!
+ * Load a flag set where the possible flags are not known at compile-time.
+ * Inno Setup stores flag sets as packed bitfields: 1 byte for every 8 flags
+ * The only exception is that 3-byte bitfields are padded to 4 bytes for non-16-bit builds.
+ */
template <class Enum>
class stored_flag_reader {
@@ -181,6 +199,10 @@ class stored_flag_reader {
typedef Enum enum_type;
typedef flags<enum_type> flag_type;
+private:
+
+ const size_t pad_bits;
+
std::istream & is;
typedef uint8_t stored_type;
@@ -191,13 +213,18 @@ class stored_flag_reader {
flag_type result;
- size_t bits;
+ size_t bytes;
+
+public:
- explicit stored_flag_reader(std::istream & _is) : is(_is), pos(0), result(0), bits(0) { }
+ explicit stored_flag_reader(std::istream & _is, size_t pad_bits = 32)
+ : pad_bits(pad_bits), is(_is), pos(0), result(0), bytes(0) { }
+ //! Declare the next possible flag.
void add(enum_type flag) {
if(pos == 0) {
+ bytes++;
buffer = load_number<stored_type>(is);
}
@@ -206,11 +233,13 @@ class stored_flag_reader {
}
pos = (pos + 1) % stored_bits;
-
- bits++;
}
operator flag_type() const {
+ if(bytes == 3 && pad_bits == 32) {
+ // 3-byte sets are padded to 4 bytes
+ (void)load_number<stored_type>(is);
+ }
return result;
}
@@ -221,7 +250,8 @@ class stored_flag_reader<flags<Enum> > : public stored_flag_reader<Enum> {
public:
- explicit stored_flag_reader(std::istream & is) : stored_flag_reader<Enum>(is) { }
+ explicit stored_flag_reader(std::istream & is, size_t pad_bits = 32)
+ : stored_flag_reader<Enum>(is, pad_bits) { }
};

0 comments on commit 273f095

Please sign in to comment.