aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-02-20 19:17:25 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-02-20 19:17:25 +0200
commit9539f5fe95589c9fc6c53290b4ed5a1af42e0d8c (patch)
tree7ff9db0c33b0ac925e4800d93bd5dee28a55520f
parent7e3616382296533e5016caec792b88a6b8556268 (diff)
Allow empty base64Binary value space per spec
-rw-r--r--libxsde/xsde/cxx/parser/non-validating/base64-binary.cxx97
-rw-r--r--libxsde/xsde/cxx/parser/validating/base64-binary.cxx135
-rw-r--r--tests/cxx/parser/validation/built-in/binary/driver.cxx21
3 files changed, 130 insertions, 123 deletions
diff --git a/libxsde/xsde/cxx/parser/non-validating/base64-binary.cxx b/libxsde/xsde/cxx/parser/non-validating/base64-binary.cxx
index ac5de47..be48cb0 100644
--- a/libxsde/xsde/cxx/parser/non-validating/base64-binary.cxx
+++ b/libxsde/xsde/cxx/parser/non-validating/base64-binary.cxx
@@ -180,10 +180,10 @@ namespace xsde
str_.truncate (size);
}
- // Our length should be a multiple of four.
+ // Our length should be a multiple of four but it can also be 0.
//
size_type quad_count = size / 4;
- size_type capacity = quad_count * 3 + 1;
+ size_type capacity = quad_count != 0 ? quad_count * 3 + 1 : 0;
#ifdef XSDE_EXCEPTIONS
buf_->size (capacity);
@@ -194,71 +194,74 @@ namespace xsde
return 0;
}
#endif
- char* dst = buf_->data ();
+ if (quad_count != 0)
+ {
+ char* dst = buf_->data ();
- // Source and destination indexes.
- //
- size_type si = 0;
- size_type di = 0;
+ // Source and destination indexes.
+ //
+ size_type si = 0;
+ size_type di = 0;
- // Process all quads except the last one.
- //
- unsigned char b1, b2, b3, b4;
+ // Process all quads except the last one.
+ //
+ unsigned char b1, b2, b3, b4;
- for (size_type q = 0; q < quad_count - 1; ++q)
- {
- b1 = base64_decode (src[si++]);
- b2 = base64_decode (src[si++]);
- b3 = base64_decode (src[si++]);
- b4 = base64_decode (src[si++]);
+ for (size_type q = 0; q < quad_count - 1; ++q)
+ {
+ b1 = base64_decode (src[si++]);
+ b2 = base64_decode (src[si++]);
+ b3 = base64_decode (src[si++]);
+ b4 = base64_decode (src[si++]);
- dst[di++] = (b1 << 2) | (b2 >> 4);
- dst[di++] = (b2 << 4) | (b3 >> 2);
- dst[di++] = (b3 << 6) | b4;
- }
+ dst[di++] = (b1 << 2) | (b2 >> 4);
+ dst[di++] = (b2 << 4) | (b3 >> 2);
+ dst[di++] = (b3 << 6) | b4;
+ }
- // Process the last quad. The first two octets are always there.
- //
- b1 = base64_decode (src[si++]);
- b2 = base64_decode (src[si++]);
+ // Process the last quad. The first two octets are always there.
+ //
+ b1 = base64_decode (src[si++]);
+ b2 = base64_decode (src[si++]);
- char e3 = src[si++];
- char e4 = src[si++];
+ char e3 = src[si++];
+ char e4 = src[si++];
- if (e4 == '=')
- {
- if (e3 == '=')
+ if (e4 == '=')
{
- // Two pads. Last 4 bits in b2 should be zero.
- //
- dst[di++] = (b1 << 2) | (b2 >> 4);
+ if (e3 == '=')
+ {
+ // Two pads. Last 4 bits in b2 should be zero.
+ //
+ dst[di++] = (b1 << 2) | (b2 >> 4);
+ }
+ else
+ {
+ // One pad. Last 2 bits in b3 should be zero.
+ //
+ b3 = base64_decode (e3);
+
+ dst[di++] = (b1 << 2) | (b2 >> 4);
+ dst[di++] = (b2 << 4) | (b3 >> 2);
+ }
}
else
{
- // One pad. Last 2 bits in b3 should be zero.
+ // No pads.
//
b3 = base64_decode (e3);
+ b4 = base64_decode (e4);
dst[di++] = (b1 << 2) | (b2 >> 4);
dst[di++] = (b2 << 4) | (b3 >> 2);
+ dst[di++] = (b3 << 6) | b4;
}
- }
- else
- {
- // No pads.
- //
- b3 = base64_decode (e3);
- b4 = base64_decode (e4);
- dst[di++] = (b1 << 2) | (b2 >> 4);
- dst[di++] = (b2 << 4) | (b3 >> 2);
- dst[di++] = (b3 << 6) | b4;
+ // Set the real size.
+ //
+ buf_->size (di);
}
- // Set the real size.
- //
- buf_->size (di);
-
buffer* r = buf_;
buf_ = 0;
return r;
diff --git a/libxsde/xsde/cxx/parser/validating/base64-binary.cxx b/libxsde/xsde/cxx/parser/validating/base64-binary.cxx
index 5852da4..e1f35e7 100644
--- a/libxsde/xsde/cxx/parser/validating/base64-binary.cxx
+++ b/libxsde/xsde/cxx/parser/validating/base64-binary.cxx
@@ -180,16 +180,16 @@ namespace xsde
str_.truncate (size);
}
- // Our length should be a multiple of four.
+ // Our length should be a multiple of four but if can also be 0.
//
- if (size == 0 || size % 4 != 0)
+ if (size % 4 != 0)
{
_schema_error (schema_error::invalid_base64_binary_value);
return;
}
size_type quad_count = size / 4;
- size_type capacity = quad_count * 3 + 1;
+ size_type capacity = quad_count != 0 ? quad_count * 3 + 1 : 0;
#ifdef XSDE_EXCEPTIONS
buf_->size (capacity);
@@ -200,70 +200,89 @@ namespace xsde
return;
}
#endif
- char* dst = buf_->data ();
+ if (quad_count != 0)
+ {
+ char* dst = buf_->data ();
- // Source and destination indexes.
- //
- size_type si = 0;
- size_type di = 0;
+ // Source and destination indexes.
+ //
+ size_type si = 0;
+ size_type di = 0;
- // Process all quads except the last one.
- //
- unsigned char b1, b2, b3, b4;
+ // Process all quads except the last one.
+ //
+ unsigned char b1, b2, b3, b4;
- for (size_type q = 0; q < quad_count - 1; ++q)
- {
+ for (size_type q = 0; q < quad_count - 1; ++q)
+ {
+ b1 = base64_decode (src[si++]);
+ b2 = base64_decode (src[si++]);
+ b3 = base64_decode (src[si++]);
+ b4 = base64_decode (src[si++]);
+
+ if (b1 == 0xFF || b2 == 0xFF || b3 == 0xFF || b4 == 0xFF)
+ {
+ _schema_error (schema_error::invalid_base64_binary_value);
+ return;
+ }
+
+ dst[di++] = (b1 << 2) | (b2 >> 4);
+ dst[di++] = (b2 << 4) | (b3 >> 2);
+ dst[di++] = (b3 << 6) | b4;
+ }
+
+ // Process the last quad. The first two octets are always there.
+ //
b1 = base64_decode (src[si++]);
b2 = base64_decode (src[si++]);
- b3 = base64_decode (src[si++]);
- b4 = base64_decode (src[si++]);
- if (b1 == 0xFF || b2 == 0xFF || b3 == 0xFF || b4 == 0xFF)
+ if (b1 == 0xFF || b2 == 0xFF)
{
_schema_error (schema_error::invalid_base64_binary_value);
return;
}
- dst[di++] = (b1 << 2) | (b2 >> 4);
- dst[di++] = (b2 << 4) | (b3 >> 2);
- dst[di++] = (b3 << 6) | b4;
- }
-
- // Process the last quad. The first two octets are always there.
- //
- b1 = base64_decode (src[si++]);
- b2 = base64_decode (src[si++]);
-
- if (b1 == 0xFF || b2 == 0xFF)
- {
- _schema_error (schema_error::invalid_base64_binary_value);
- return;
- }
-
- char e3 = src[si++];
- char e4 = src[si++];
+ char e3 = src[si++];
+ char e4 = src[si++];
- if (e4 == '=')
- {
- if (e3 == '=')
+ if (e4 == '=')
{
- // Two pads. Last 4 bits in b2 should be zero.
- //
- if ((b2 & 0x0F) != 0)
+ if (e3 == '=')
{
- _schema_error (schema_error::invalid_base64_binary_value);
- return;
+ // Two pads. Last 4 bits in b2 should be zero.
+ //
+ if ((b2 & 0x0F) != 0)
+ {
+ _schema_error (schema_error::invalid_base64_binary_value);
+ return;
+ }
+
+ dst[di++] = (b1 << 2) | (b2 >> 4);
+ }
+ else
+ {
+ // One pad. Last 2 bits in b3 should be zero.
+ //
+ b3 = base64_decode (e3);
+
+ if (b3 == 0xFF || (b3 & 0x03) != 0)
+ {
+ _schema_error (schema_error::invalid_base64_binary_value);
+ return;
+ }
+
+ dst[di++] = (b1 << 2) | (b2 >> 4);
+ dst[di++] = (b2 << 4) | (b3 >> 2);
}
-
- dst[di++] = (b1 << 2) | (b2 >> 4);
}
else
{
- // One pad. Last 2 bits in b3 should be zero.
+ // No pads.
//
b3 = base64_decode (e3);
+ b4 = base64_decode (e4);
- if (b3 == 0xFF || (b3 & 0x03) != 0)
+ if (b3 == 0xFF || b4 == 0xFF)
{
_schema_error (schema_error::invalid_base64_binary_value);
return;
@@ -271,29 +290,13 @@ namespace xsde
dst[di++] = (b1 << 2) | (b2 >> 4);
dst[di++] = (b2 << 4) | (b3 >> 2);
- }
- }
- else
- {
- // No pads.
- //
- b3 = base64_decode (e3);
- b4 = base64_decode (e4);
-
- if (b3 == 0xFF || b4 == 0xFF)
- {
- _schema_error (schema_error::invalid_base64_binary_value);
- return;
+ dst[di++] = (b3 << 6) | b4;
}
- dst[di++] = (b1 << 2) | (b2 >> 4);
- dst[di++] = (b2 << 4) | (b3 >> 2);
- dst[di++] = (b3 << 6) | b4;
+ // Set the real size.
+ //
+ buf_->size (di);
}
-
- // Set the real size.
- //
- buf_->size (di);
}
buffer* base64_binary_pimpl::
diff --git a/tests/cxx/parser/validation/built-in/binary/driver.cxx b/tests/cxx/parser/validation/built-in/binary/driver.cxx
index 0496f2e..75cfa5d 100644
--- a/tests/cxx/parser/validation/built-in/binary/driver.cxx
+++ b/tests/cxx/parser/validation/built-in/binary/driver.cxx
@@ -65,6 +65,17 @@ main ()
base64_binary_pimpl p;
p.pre ();
p._pre_impl (c);
+ p._characters ("");
+ p._post ();
+ assert (!c.error_type () &&
+ compare (p.post_base64_binary (), "", 0));
+ }
+
+ {
+ context c;
+ base64_binary_pimpl p;
+ p.pre ();
+ p._pre_impl (c);
p._characters (" \t\n ");
p._characters ("MTIzND ");
p._characters ("VhYmNqaw = = ");
@@ -138,16 +149,6 @@ main ()
base64_binary_pimpl p;
p.pre ();
p._pre_impl (c);
- // p._characters ("");
- p._post ();
- assert (c.schema_error () == schema_error::invalid_base64_binary_value);
- }
-
- {
- context c;
- base64_binary_pimpl p;
- p.pre ();
- p._pre_impl (c);
p._characters ("YQ");
p._post ();
assert (c.schema_error () == schema_error::invalid_base64_binary_value);