Skip to content

Commit 9f3a61d

Browse files
Support for attributes in illustration name
Parsing of the illustration metadata item name now supports attributes too. Also, an illustration metadata item name is now considered invalid if it doesn't match the string generated from the result of the parsing (which can be, for example, due to leading zeros in width and/or height values, leading and/or trailing zeros in the scale value, wrong order of attributes, etc).
1 parent 8ab3ff1 commit 9f3a61d

File tree

3 files changed

+40
-15
lines changed

3 files changed

+40
-15
lines changed

include/zim/illustration.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ class LIBZIM_API Attributes : public std::map<std::string, std::string>
3838
Attributes(const std::initializer_list<ImplType::value_type>& x)
3939
: ImplType(x)
4040
{}
41+
42+
static Attributes parse(const std::string& s);
4143
};
4244

4345
/**
@@ -49,8 +51,6 @@ struct LIBZIM_API IllustrationInfo
4951
uint32_t height; // in CSS pixels
5052
float scale; // devicePixelRatio value of the targeted display media
5153
Attributes extraAttributes; // additional attributes of the illustration
52-
// (not used yet but introduced beforehand in
53-
// order to avoid an ABI change later)
5454

5555
std::string asMetadataItemName() const;
5656
static IllustrationInfo fromMetadataItemName(const std::string& s);

src/tools.cpp

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -128,24 +128,45 @@ std::string zim::IllustrationInfo::asMetadataItemName() const
128128
return oss.str();
129129
}
130130

131+
zim::Attributes zim::Attributes::parse(const std::string& s)
132+
{
133+
zim::Attributes a;
134+
for (const std::string& nameAndValue : split(s, ";") ) {
135+
const auto i = nameAndValue.find('=');
136+
const std::string name = nameAndValue.substr(0, i);
137+
const std::string value = i == std::string::npos
138+
? ""
139+
: nameAndValue.substr(i+1);
140+
a[name] = value;
141+
}
142+
return a;
143+
}
144+
131145
zim::IllustrationInfo zim::IllustrationInfo::fromMetadataItemName(const std::string& s)
132146
{
133147
int nw(0), nh(0), ns(0), nEnd(0);
134148
long int w(-1), h(-1);
135149
float scale(0);
136150

137-
const char fmt[] = "Illustration_%n%ldx%n%ld@%n%f%n";
138-
if ( sscanf(s.c_str(), fmt, &nw, &w, &nh, &h, &ns, &scale, &nEnd) == 3
139-
&& (size_t)nEnd == s.size()
140-
&& !isspace(s[nw])
141-
&& !isspace(s[nh])
142-
&& !isspace(s[ns])
143-
&& w >= 0
144-
&& h >= 0
145-
&& scale >= 0 ) {
146-
return IllustrationInfo{uint32_t(w), uint32_t(h), scale, {}};
151+
const char fmt[] = "Illustration_%n%ldx%n%ld@%n%f%n;";
152+
if ( sscanf(s.c_str(), fmt, &nw, &w, &nh, &h, &ns, &scale, &nEnd) != 3
153+
|| isspace(s[nw])
154+
|| isspace(s[nh])
155+
|| isspace(s[ns])
156+
|| w < 0
157+
|| h < 0
158+
|| scale < 0
159+
|| (size_t(nEnd) != s.size() && s[nEnd] != ';') ) {
160+
throw std::runtime_error("Invalid name of illustration metadata item");
147161
}
148-
throw std::runtime_error("");
162+
163+
const auto attrStart = std::min(s.size(), size_t(nEnd) + 1);
164+
const auto attributes = Attributes::parse(s.substr(attrStart));
165+
const auto ii = IllustrationInfo{uint32_t(w), uint32_t(h), scale, attributes};
166+
if ( ii.asMetadataItemName() != s ) {
167+
throw std::runtime_error("Invalid name of illustration metadata item");
168+
}
169+
return ii;
149170
}
150171

151172
uint32_t zim::randomNumber(uint32_t max)

test/illustrations.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,11 @@ TEST(Illustrations, parsingOfValidInput)
3333

3434
CHECK("Illustration_0x0@1", ({ 0, 0, 1.0, {} }) );
3535
CHECK("Illustration_1x1@1", ({ 1, 1, 1.0, {} }) );
36-
CHECK("Illustration_01x01@1", ({ 1, 1, 1.0, {} }) );
3736
CHECK("Illustration_64x64@1", ({ 64, 64, 1.0, {} }) );
3837
CHECK("Illustration_64x64@2", ({ 64, 64, 2.0, {} }) );
3938
CHECK("Illustration_64x48@2", ({ 64, 48, 2.0, {} }) );
39+
CHECK("Illustration_64x64@1;ui=dark", ({ 64, 64, 1.0, {{"ui", "dark"}} }));
40+
CHECK("Illustration_48x64@1.5;lang=fr;ui=dark", ({ 48, 64, 1.5, {{"lang", "fr"}, {"ui", "dark"}} }));
4041
#undef CHECK
4142
}
4243

@@ -46,17 +47,20 @@ TEST(Illustrations, parsingOfInvalidInput)
4647
ASSERT_THROW(zim::IllustrationInfo::fromMetadataItemName(str), \
4748
std::runtime_error)
4849

50+
CHECK_PARSING_OF_INVALID_INPUT("Illustration_01x01@1");
51+
CHECK_PARSING_OF_INVALID_INPUT("Illustration_48x48@1;");
4952
CHECK_PARSING_OF_INVALID_INPUT("Illstration_64x64@1");
5053
CHECK_PARSING_OF_INVALID_INPUT("Illstration_");
5154
CHECK_PARSING_OF_INVALID_INPUT("Illustration_64x@1");
52-
CHECK_PARSING_OF_INVALID_INPUT("Illustration_64x64@1;scheme=light");
5355
CHECK_PARSING_OF_INVALID_INPUT("Illustration_64x");
5456
CHECK_PARSING_OF_INVALID_INPUT("Illustration_64x64");
5557
CHECK_PARSING_OF_INVALID_INPUT("Illustration_-32x-32@1");
5658
CHECK_PARSING_OF_INVALID_INPUT("Illustration_ 64x64@1");
5759
CHECK_PARSING_OF_INVALID_INPUT("Illustration_64x 64@1");
5860
CHECK_PARSING_OF_INVALID_INPUT("Illustration_ 64x 64@1");
5961
CHECK_PARSING_OF_INVALID_INPUT("Illustration_1 28x1 28@1");
62+
CHECK_PARSING_OF_INVALID_INPUT("Illustration_48x64@1.5000");
63+
CHECK_PARSING_OF_INVALID_INPUT("Illustration_48x64@1.5;ui=dark;lang=fr");
6064

6165
#undef CHECK_PARSING_OF_INVALID_INPUT
6266
}

0 commit comments

Comments
 (0)