@@ -154,7 +154,7 @@ static TRI_index_operator_t* buildRangeOperator (TRI_json_t const* lowerBound,
154
154
lowerOperator.release ();
155
155
upperOperator.release ();
156
156
return rangeOperator.release ();
157
- };
157
+ }
158
158
159
159
// //////////////////////////////////////////////////////////////////////////////
160
160
// / @brief frees an element in the skiplist
@@ -1331,12 +1331,17 @@ IndexIterator* SkiplistIndex::iteratorForCondition (IndexIteratorContext* contex
1331
1331
nullArray.add (Json (Json::Null));
1332
1332
std::unique_ptr<TRI_index_operator_t> unboundOperator (TRI_CreateIndexOperator (TRI_GE_INDEX_OPERATOR, nullptr ,
1333
1333
nullptr , nullArray.steal (), _shaper, 1 ));
1334
- std::vector<TRI_index_operator_t*> searchValues ({unboundOperator.get ()});
1334
+ std::vector<TRI_index_operator_t*> searchValues ({ unboundOperator.get () });
1335
1335
unboundOperator.release ();
1336
1336
1337
- TRI_IF_FAILURE (" SkiplistIndex::noSortIterator" ) {
1337
+ TRI_IF_FAILURE (" SkiplistIndex::noSortIterator" ) {
1338
+ // prevent a (false-positive) memleak here
1339
+ for (auto & it : searchValues) {
1340
+ delete it;
1341
+ }
1338
1342
THROW_ARANGO_EXCEPTION (TRI_ERROR_DEBUG);
1339
1343
}
1344
+
1340
1345
return new SkiplistIndexIterator (this , searchValues, reverse);
1341
1346
}
1342
1347
@@ -1477,102 +1482,117 @@ IndexIterator* SkiplistIndex::iteratorForCondition (IndexIteratorContext* contex
1477
1482
std::vector<TRI_index_operator_t*> searchValues;
1478
1483
searchValues.reserve (maxPermutations);
1479
1484
1480
- if (usedFields == 0 ) {
1481
- // We have a range query based on the first _field
1482
- auto op = buildRangeOperator (lower.get (), includeLower, upper.get (), includeUpper, nullptr , _shaper);
1483
- if (op != nullptr ) {
1484
- searchValues.emplace_back (op);
1485
- TRI_IF_FAILURE (" SkiplistIndex::onlyRangeOperator" ) {
1486
- THROW_ARANGO_EXCEPTION (TRI_ERROR_DEBUG);
1487
- }
1488
- }
1489
- }
1490
- else {
1491
- bool done = false ;
1492
- // create all permutations
1493
- while (! done) {
1494
- std::unique_ptr<TRI_json_t> parameter (TRI_CreateArrayJson (TRI_UNKNOWN_MEM_ZONE, usedFields));
1495
-
1496
- bool valid = true ;
1497
- for (size_t i = 0 ; i < usedFields; ++i) {
1498
- TRI_ASSERT (i < permutationStates.size ());
1499
- auto & state = permutationStates[i];
1500
- std::unique_ptr<TRI_json_t> json (state.getValue ()->toJsonValue (TRI_UNKNOWN_MEM_ZONE));
1501
-
1502
- if (json == nullptr ) {
1503
- valid = false ;
1504
- break ;
1485
+ try {
1486
+ if (usedFields == 0 ) {
1487
+ // We have a range query based on the first _field
1488
+ std::unique_ptr<TRI_index_operator_t> op (buildRangeOperator (lower.get (), includeLower, upper.get (), includeUpper, nullptr , _shaper));
1489
+
1490
+ if (op != nullptr ) {
1491
+ searchValues.emplace_back (op.get ());
1492
+ op.release ();
1493
+
1494
+ TRI_IF_FAILURE (" SkiplistIndex::onlyRangeOperator" ) {
1495
+ THROW_ARANGO_EXCEPTION (TRI_ERROR_DEBUG);
1505
1496
}
1506
- TRI_PushBack3ArrayJson (TRI_UNKNOWN_MEM_ZONE, parameter.get (), json.release ());
1507
1497
}
1508
-
1509
- if (valid) {
1510
- std::unique_ptr<TRI_index_operator_t> tmpOp (TRI_CreateIndexOperator (TRI_EQ_INDEX_OPERATOR,
1511
- nullptr ,
1512
- nullptr ,
1513
- parameter.get (),
1514
- _shaper,
1515
- usedFields));
1516
- // Note we create a new RangeOperator always.
1517
- std::unique_ptr<TRI_index_operator_t> rangeOperator (buildRangeOperator (lower.get (), includeLower, upper.get (), includeUpper, parameter.get (), _shaper));
1518
- parameter.release ();
1519
-
1520
- if (rangeOperator != nullptr ) {
1521
- std::unique_ptr<TRI_index_operator_t> combinedOp (TRI_CreateIndexOperator (TRI_AND_INDEX_OPERATOR,
1522
- tmpOp.get (),
1523
- rangeOperator.get (),
1524
- nullptr ,
1525
- _shaper,
1526
- 2 ));
1527
- rangeOperator.release ();
1528
- tmpOp.release ();
1529
- searchValues.emplace_back (combinedOp.get ());
1530
- TRI_IF_FAILURE (" SkiplistIndex::rangeOperatorNoTmp" ) {
1531
- THROW_ARANGO_EXCEPTION (TRI_ERROR_DEBUG);
1498
+ }
1499
+ else {
1500
+ bool done = false ;
1501
+ // create all permutations
1502
+ while (! done) {
1503
+ std::unique_ptr<TRI_json_t> parameter (TRI_CreateArrayJson (TRI_UNKNOWN_MEM_ZONE, usedFields));
1504
+
1505
+ bool valid = true ;
1506
+ for (size_t i = 0 ; i < usedFields; ++i) {
1507
+ TRI_ASSERT (i < permutationStates.size ());
1508
+ auto & state = permutationStates[i];
1509
+ std::unique_ptr<TRI_json_t> json (state.getValue ()->toJsonValue (TRI_UNKNOWN_MEM_ZONE));
1510
+
1511
+ if (json == nullptr ) {
1512
+ valid = false ;
1513
+ break ;
1532
1514
}
1533
- combinedOp. release ();
1515
+ TRI_PushBack3ArrayJson (TRI_UNKNOWN_MEM_ZONE, parameter. get (), json. release () );
1534
1516
}
1535
- else {
1536
- if (tmpOp != nullptr ) {
1537
- searchValues.emplace_back (tmpOp.get ());
1538
- TRI_IF_FAILURE (" SkiplistIndex::rangeOperatorTmp" ) {
1517
+
1518
+ if (valid) {
1519
+ std::unique_ptr<TRI_index_operator_t> tmpOp (TRI_CreateIndexOperator (TRI_EQ_INDEX_OPERATOR,
1520
+ nullptr ,
1521
+ nullptr ,
1522
+ parameter.get (),
1523
+ _shaper,
1524
+ usedFields));
1525
+ // Note we create a new RangeOperator always.
1526
+ std::unique_ptr<TRI_index_operator_t> rangeOperator (buildRangeOperator (lower.get (), includeLower, upper.get (), includeUpper, parameter.get (), _shaper));
1527
+ parameter.release ();
1528
+
1529
+ if (rangeOperator != nullptr ) {
1530
+ std::unique_ptr<TRI_index_operator_t> combinedOp (TRI_CreateIndexOperator (TRI_AND_INDEX_OPERATOR,
1531
+ tmpOp.get (),
1532
+ rangeOperator.get (),
1533
+ nullptr ,
1534
+ _shaper,
1535
+ 2 ));
1536
+ rangeOperator.release ();
1537
+ tmpOp.release ();
1538
+ searchValues.emplace_back (combinedOp.get ());
1539
+ combinedOp.release ();
1540
+ TRI_IF_FAILURE (" SkiplistIndex::rangeOperatorNoTmp" ) {
1539
1541
THROW_ARANGO_EXCEPTION (TRI_ERROR_DEBUG);
1540
1542
}
1541
- tmpOp.release ();
1543
+ }
1544
+ else {
1545
+ if (tmpOp != nullptr ) {
1546
+ searchValues.emplace_back (tmpOp.get ());
1547
+ tmpOp.release ();
1548
+ TRI_IF_FAILURE (" SkiplistIndex::rangeOperatorTmp" ) {
1549
+ THROW_ARANGO_EXCEPTION (TRI_ERROR_DEBUG);
1550
+ }
1551
+ }
1542
1552
}
1543
1553
}
1544
- }
1545
1554
1546
- size_t const np = permutationStates.size () - 1 ;
1547
- size_t current = 0 ;
1548
- // now permute
1549
- while (true ) {
1550
- if (++permutationStates[np - current].current < permutationStates[np - current].n ) {
1551
- current = 0 ;
1552
- // abort inner iteration
1553
- break ;
1554
- }
1555
+ size_t const np = permutationStates.size () - 1 ;
1556
+ size_t current = 0 ;
1557
+ // now permute
1558
+ while (true ) {
1559
+ if (++permutationStates[np - current].current < permutationStates[np - current].n ) {
1560
+ current = 0 ;
1561
+ // abort inner iteration
1562
+ break ;
1563
+ }
1555
1564
1556
- permutationStates[np - current].current = 0 ;
1565
+ permutationStates[np - current].current = 0 ;
1557
1566
1558
- if (++current >= usedFields) {
1559
- done = true ;
1560
- break ;
1567
+ if (++current >= usedFields) {
1568
+ done = true ;
1569
+ break ;
1570
+ }
1571
+ // next inner iteration
1561
1572
}
1562
- // next inner iteration
1563
1573
}
1564
1574
}
1575
+
1576
+ if (searchValues.empty ()) {
1577
+ return nullptr ;
1578
+ }
1579
+
1580
+ if (reverse) {
1581
+ std::reverse (searchValues.begin (), searchValues.end ());
1582
+ }
1583
+
1584
+ TRI_IF_FAILURE (" SkiplistIndex::noIterator" ) {
1585
+ THROW_ARANGO_EXCEPTION (TRI_ERROR_DEBUG);
1586
+ }
1565
1587
}
1566
- if (searchValues.empty ()) {
1567
- return nullptr ;
1568
- }
1569
- if (reverse) {
1570
- std::reverse (searchValues.begin (), searchValues.end ());
1588
+ catch (...) {
1589
+ // prevent memleak here
1590
+ for (auto & it : searchValues) {
1591
+ delete it;
1592
+ }
1593
+ throw ;
1571
1594
}
1572
1595
1573
- TRI_IF_FAILURE (" SkiplistIndex::noIterator" ) {
1574
- THROW_ARANGO_EXCEPTION (TRI_ERROR_DEBUG);
1575
- }
1576
1596
return new SkiplistIndexIterator (this , searchValues, reverse);
1577
1597
}
1578
1598
0 commit comments