]> www.ginac.de Git - ginac.git/commitdiff
 author Alexei Sheplyakov Sat, 9 Oct 2010 16:39:41 +0000 (18:39 +0200) committer Richard Kreckel Sat, 9 Oct 2010 16:40:59 +0000 (18:40 +0200)
algebraic_match_mul_with_mul() iterates over operands of mul, that is

for (size_t i=0; i<e.nops(); ++i)

However, the size of arrays (`vectors' in STL speak) passed to this
function is seq.size(), which is nops() - 1 for any mul object. Thus
algebraic_match_mul_with_mul() accesses beyond the arrays limit. Usually
it's not a problem, since any reasonable implementation of std::vector<bool>
packs booleans into ints (or longs). However, some STL implementations
(in particular, the one shipped with msvc) are more picky, and access
beyond the vector<bool> limits results in a segfault. Therefore let's
play safe and allocate proper number of elements (that is, nops()) for
those arrays (subsed and currsubsed).

 ginac/mul.cpp patch | blob | history

@@ -729,6 +729,9 @@ bool algebraic_match_mul_with_mul(const mul &e, const ex &pat, exmap& repls,
int factor, int &nummatches, const std::vector<bool> &subsed,
std::vector<bool> &matched)
{
int factor, int &nummatches, const std::vector<bool> &subsed,
std::vector<bool> &matched)
{
+       GINAC_ASSERT(subsed.size() == e.nops());
+       GINAC_ASSERT(matched.size() == e.nops());
+
if (factor == (int)pat.nops())
return true;

if (factor == (int)pat.nops())
return true;

@@ -760,8 +763,8 @@ bool mul::has(const ex & pattern, unsigned options) const
if(is_a<mul>(pattern)) {
exmap repls;
int nummatches = std::numeric_limits<int>::max();
if(is_a<mul>(pattern)) {
exmap repls;
int nummatches = std::numeric_limits<int>::max();
-               std::vector<bool> subsed(seq.size(), false);
-               std::vector<bool> matched(seq.size(), false);
+               std::vector<bool> subsed(nops(), false);
+               std::vector<bool> matched(nops(), false);
if(algebraic_match_mul_with_mul(*this, pattern, repls, 0, nummatches,
subsed, matched))
return true;
if(algebraic_match_mul_with_mul(*this, pattern, repls, 0, nummatches,
subsed, matched))
return true;
@@ -771,8 +774,7 @@ bool mul::has(const ex & pattern, unsigned options) const

ex mul::algebraic_subs_mul(const exmap & m, unsigned options) const
{

ex mul::algebraic_subs_mul(const exmap & m, unsigned options) const
{
-       std::vector<bool> subsed(seq.size(), false);
-       exvector subsresult(seq.size());
+       std::vector<bool> subsed(nops(), false);
ex divide_by = 1;
ex multiply_by = 1;

ex divide_by = 1;
ex multiply_by = 1;

@@ -781,7 +783,7 @@ ex mul::algebraic_subs_mul(const exmap & m, unsigned options) const
if (is_exactly_a<mul>(it->first)) {
retry1:
int nummatches = std::numeric_limits<int>::max();
if (is_exactly_a<mul>(it->first)) {
retry1:
int nummatches = std::numeric_limits<int>::max();
-                       std::vector<bool> currsubsed(seq.size(), false);
+                       std::vector<bool> currsubsed(nops(), false);
exmap repls;

if(!algebraic_match_mul_with_mul(*this, it->first, repls, 0, nummatches, subsed, currsubsed))
exmap repls;

if(!algebraic_match_mul_with_mul(*this, it->first, repls, 0, nummatches, subsed, currsubsed))