Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r86687 - in trunk/tools/quickbook: src test
From: dnljms_at_[hidden]
Date: 2013-11-13 16:49:05


Author: danieljames
Date: 2013-11-13 16:49:05 EST (Wed, 13 Nov 2013)
New Revision: 86687
URL: http://svn.boost.org/trac/boost/changeset/86687

Log:
Validate and process link values.

Text files modified:
   trunk/tools/quickbook/src/actions.cpp | 51 ++++++++++++++++++++++++++++++++++++---
   trunk/tools/quickbook/src/utils.cpp | 30 +++++++++++++++++++---
   trunk/tools/quickbook/src/utils.hpp | 7 +++++
   trunk/tools/quickbook/test/link-1_7.gold | 3 --
   trunk/tools/quickbook/test/link-1_7.quickbook | 3 --
   5 files changed, 79 insertions(+), 15 deletions(-)

Modified: trunk/tools/quickbook/src/actions.cpp
==============================================================================
--- trunk/tools/quickbook/src/actions.cpp Wed Nov 13 16:48:40 2013 (r86686)
+++ trunk/tools/quickbook/src/actions.cpp 2013-11-13 16:49:05 EST (Wed, 13 Nov 2013) (r86687)
@@ -73,6 +73,38 @@
             state.anchors.push_back(placeholder);
             return placeholder;
         }
+
+ std::string validate_id(quickbook::state& state,
+ quickbook::value const& id_value)
+ {
+ bool valid = true;
+ std::string id = id_value.is_encoded() ?
+ id_value.get_encoded() : detail::to_s(id_value.get_quickbook());
+
+ // Special case since I use dollar ids for id placeholders.
+ if (id[0] == '$') { valid = false; id[0] = '_'; }
+
+ if (qbk_version_n >= 107u) {
+ char const* allowed_punctuation = "_.-";
+
+ BOOST_FOREACH(char c, id) {
+ if (!std::isalnum(c) &&
+ !std::strchr(allowed_punctuation, c))
+ valid = false;
+ }
+ }
+
+ if (!valid) {
+ detail::outerr(id_value.get_file(), id_value.get_position())
+ << "Invalid id: "
+ << (id_value.is_encoded() ? id_value.get_encoded() :
+ detail::to_s(id_value.get_quickbook()))
+ << std::endl;
+ ++state.error_count;
+ }
+
+ return id;
+ }
     }
 
     bool quickbook_range::in_range() const {
@@ -1511,10 +1543,21 @@
         value content = values.consume();
         values.finish();
 
- // Note: dst is never actually encoded as boostbook, which
- // is why the result is called with 'print_string' later.
- std::string dst = dst_value.is_encoded() ?
- dst_value.get_encoded() : detail::to_s(dst_value.get_quickbook());
+ std::string dst;
+
+ if (link.get_tag() == phrase_tags::link) {
+ dst = validate_id(state, dst_value);
+ }
+ else {
+ dst = dst_value.is_encoded() ?
+ dst_value.get_encoded() :
+ detail::to_s(dst_value.get_quickbook());
+
+ // TODO: Might be better to have an error for some invalid urls.
+ if (link.get_tag() == phrase_tags::url) {
+ dst = detail::partially_escape_uri(dst);
+ }
+ }
         
         state.phrase << markup.pre;
         detail::print_string(dst, state.phrase.get());

Modified: trunk/tools/quickbook/src/utils.cpp
==============================================================================
--- trunk/tools/quickbook/src/utils.cpp Wed Nov 13 16:48:40 2013 (r86686)
+++ trunk/tools/quickbook/src/utils.cpp 2013-11-13 16:49:05 EST (Wed, 13 Nov 2013) (r86687)
@@ -66,25 +66,45 @@
         return static_cast<char>(std::tolower(static_cast<unsigned char>(ch)));
     }
 
- std::string escape_uri(std::string uri_param)
+ static std::string escape_uri_impl(std::string& uri_param, char const* mark)
     {
+ // Extra capital characters for validating percent escapes.
+ static char const hex[] = "0123456789abcdefABCDEF";
+
         std::string uri;
         uri.swap(uri_param);
 
         for (std::string::size_type n = 0; n < uri.size(); ++n)
         {
- static char const mark[] = "-_.!~*'()?\\/";
- if((!std::isalnum(static_cast<unsigned char>(uri[n])) || 127 < static_cast<unsigned char>(uri[n]))
- && 0 == std::strchr(mark, uri[n]))
+ if (static_cast<unsigned char>(uri[n]) > 127 ||
+ (!std::isalnum(static_cast<unsigned char>(uri[n])) &&
+ !std::strchr(mark, uri[n])) ||
+ (uri[n] == '%' && !(n + 2 < uri.size() &&
+ std::strchr(hex, uri[n+1]) &&
+ std::strchr(hex, uri[n+2]))))
             {
- static char const hex[] = "0123456789abcdef";
                 char escape[] = { hex[uri[n] / 16], hex[uri[n] % 16] };
                 uri.insert(n + 1, escape, 2);
                 uri[n] = '%';
                 n += 2;
             }
+ else if (uri[n] == '%')
+ {
+ n += 2;
+ }
         }
 
         return uri;
     }
+
+ std::string escape_uri(std::string uri_param)
+ {
+ // TODO: I don't understand this choice of characters.....
+ return escape_uri_impl(uri_param, "-_.!~*'()?\\/");
+ }
+
+ std::string partially_escape_uri(std::string uri_param)
+ {
+ return escape_uri_impl(uri_param, "-_.!~*'()?\\/:&=#%");
+ }
 }}

Modified: trunk/tools/quickbook/src/utils.hpp
==============================================================================
--- trunk/tools/quickbook/src/utils.hpp Wed Nov 13 16:48:40 2013 (r86686)
+++ trunk/tools/quickbook/src/utils.hpp 2013-11-13 16:49:05 EST (Wed, 13 Nov 2013) (r86687)
@@ -34,11 +34,18 @@
         return out_name;
     }
 
+ // URI escape string
     std::string escape_uri(std::string uri);
     inline std::string escape_uri(boost::string_ref uri) {
         return escape_uri(std::string(uri.begin(), uri.end()));
     }
 
+ // URI escape string, leaving characters generally used in URIs.
+ std::string partially_escape_uri(std::string uri);
+ inline std::string partially_escape_uri(boost::string_ref uri) {
+ return escape_uri(std::string(uri.begin(), uri.end()));
+ }
+
     inline std::string to_s(boost::string_ref x) {
         return std::string(x.begin(), x.end());
     }

Modified: trunk/tools/quickbook/test/link-1_7.gold
==============================================================================
--- trunk/tools/quickbook/test/link-1_7.gold Wed Nov 13 16:48:40 2013 (r86686)
+++ trunk/tools/quickbook/test/link-1_7.gold 2013-11-13 16:49:05 EST (Wed, 13 Nov 2013) (r86687)
@@ -21,9 +21,6 @@
     <para>
       <link linkend="link">description</link>
     </para>
- <para>
- <link linkend="link[Hello]">description</link>
- </para>
   </section>
   <section id="link_tests.side_by_side_links">
     <title><link linkend="link_tests.side_by_side_links">Side-by-side links</link></title>

Modified: trunk/tools/quickbook/test/link-1_7.quickbook
==============================================================================
--- trunk/tools/quickbook/test/link-1_7.quickbook Wed Nov 13 16:48:40 2013 (r86686)
+++ trunk/tools/quickbook/test/link-1_7.quickbook 2013-11-13 16:49:05 EST (Wed, 13 Nov 2013) (r86687)
@@ -28,9 +28,6 @@
 
 [link link[/ comment]description]
 
-[link link\[Hello\] description]
-
-
 [endsect]
 
 [section Side-by-side links]


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk