Access violation in Boost.Format using absolute tabulations

If the format string have an absolute tabulation (%t), the basic_format::clear() method throws an access violation because of this piece code in format_implementation.hpp(138): if( bound_.size()==0 || !bound_[ items_[i].argN_ ] ) Here items_[i].argN_ can be negative (defined in internals.hpp(70)), which is an invalid index to bound_[]. I think a simple check of greather than zero would suffice to fix it. Here is a code that catches it: using boost::format; format f("%0s%-32.32s:%|40t|%|.6|%|55t|%25s\n"); f % "test1" % 2.0 % "test3"; f % "test4" % 5.0 % "test6"; // calls clear() and breaks

Edson Tadeu ha escrito:
If the format string have an absolute tabulation (%t), the basic_format::clear() method throws an access violation because of this piece code in format_implementation.hpp(138):
if( bound_.size()==0 || !bound_[ items_[i].argN_ ] )
Here items_[i].argN_ can be negative (defined in internals.hpp(70)), which is an invalid index to bound_[]. I think a simple check of greather than zero would suffice to fix it. Here is a code that catches it:
using boost::format; format f("%0s%-32.32s:%|40t|%|.6|%|55t|%25s\n"); f % "test1" % 2.0 % "test3"; f % "test4" % 5.0 % "test6"; // calls clear() and breaks
Hello Edson, The test case you propose doesn't call clear() nor shows the error you refer to: instead, a boost::io::too_many_args is thrown. Am I missing something? Anyway, seems like you spotted a real problem, and the following does actually call bound_[ items_[i].argN_ ] with items_[i].argN_ negative inside basic_format::clear(), at least for the Boost.Format code in the CVS trunk: format f("%40t%1%"); int x=0; f.bind_arg(1,x); f.clear(); Can you also observe a crash with this snippet? If so, I can try to propose and commit a fix following your suggestion of adding a positiveness check in the offending if. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

Joaquín,
Actually I tried to simplify into a test case a code in a real application I
was debugging, but I forgot to put a line in it:
using boost::format;
format f("%0s%-32.32s:%|40t|%|.6|%|55t|%25s\n");
f.bind_arg(1,"");
f % "test1" % 2.0 % "test3";
f % "test4" % 5.0 % "test6"; // calls clear() and breaks
It didn't call clear() explicitly, but operator%() automatically calls it to
refresh to a new string. Your test does the same thing and is much clearer
and simpler. I got a crash on your code too, when debugging on msvc 7.
I changed the offending line to:
if( bound_.size()==0 || (items_[i].argN_ >= 0) && !bound_[
items_[i].argN_ ] )
And now it is ok here!
Regards,
Edson Tadeu M. Manoel
On 5/24/06, Joaquín Mª López Muñoz
Edson Tadeu ha escrito:
If the format string have an absolute tabulation (%t), the basic_format::clear() method throws an access violation because of this piece code in format_implementation.hpp(138):
if( bound_.size()==0 || !bound_[ items_[i].argN_ ] )
Here items_[i].argN_ can be negative (defined in internals.hpp(70)), which is an invalid index to bound_[]. I think a simple check of greather than zero would suffice to fix it. Here is a code that catches it:
using boost::format; format f("%0s%-32.32s:%|40t|%|.6|%|55t|%25s\n"); f % "test1" % 2.0 % "test3"; f % "test4" % 5.0 % "test6"; // calls clear() and breaks
Hello Edson,
The test case you propose doesn't call clear() nor shows the error you refer to: instead, a boost::io::too_many_args is thrown. Am I missing something?
Anyway, seems like you spotted a real problem, and the following does actually call bound_[ items_[i].argN_ ] with items_[i].argN_ negative inside basic_format::clear(), at least for the Boost.Format code in the CVS trunk:
format f("%40t%1%"); int x=0; f.bind_arg(1,x); f.clear();
Can you also observe a crash with this snippet? If so, I can try to propose and commit a fix following your suggestion of adding a positiveness check in the offending if.
Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Edson Tadeu ha escrito:
Joaquín,
Actually I tried to simplify into a test case a code in a real application I was debugging, but I forgot to put a line in it:
using boost::format; format f("%0s%-32.32s:%|40t|%|.6|%|55t|%25s\n "); f.bind_arg(1,""); f % "test1" % 2.0 % "test3"; f % "test4" % 5.0 % "test6"; // calls clear() and breaks
It didn't call clear() explicitly, but operator%() automatically calls it to refresh to a new string. Your test does the same thing and is much clearer and simpler. I got a crash on your code too, when debugging on msvc 7.
I changed the offending line to:
if( bound_.size()==0 || (items_[i].argN_ >= 0) && !bound_[ items_[i].argN_ ] )
And now it is ok here!
I'd say the following is marginally more correct if( bound_.size()==0 || items_[i].argN_<0 || !bound_[ items_[i].argN_ ] ) because it clears items_[i].res_ in exactly every case except for bound args while your formulation omits items_[i].res_ clearing in more cases than bound args, namely also for items_[i].argN_<0. Anyway, it probably does not matter much. Does this formulation still solve your crash? I'm posting this a a patch proposal in a separate post. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
participants (2)
-
Edson Tadeu
-
Joaquín Mª López Muñoz