Fossil SCM
fixed a cson mis-use which could cause a crash in some cases due to client-side misachtung of the reference count.
Commit
d8fd611fab83ceaae77993e6074e2c24a23786e3
Parent
8907163ea4c6614…
1 file changed
+21
-7
+21
-7
| --- src/json.c | ||
| +++ src/json.c | ||
| @@ -1567,18 +1567,21 @@ | ||
| 1567 | 1567 | while( (SQLITE_ROW==db_step(pStmt)) ){ |
| 1568 | 1568 | cson_value * row = NULL; |
| 1569 | 1569 | if(!a){ |
| 1570 | 1570 | if(!v){ |
| 1571 | 1571 | v = cson_value_new_array(); |
| 1572 | - colNamesV = cson_sqlite3_column_names(pStmt->pStmt); | |
| 1573 | - assert(NULL != colNamesV); | |
| 1574 | - colNames = cson_value_get_array(colNamesV); | |
| 1575 | - assert(NULL != colNames); | |
| 1576 | 1572 | } |
| 1577 | 1573 | a = cson_value_get_array(v); |
| 1578 | 1574 | assert(NULL!=a); |
| 1579 | 1575 | } |
| 1576 | + if(!colNames){ | |
| 1577 | + colNamesV = cson_sqlite3_column_names(pStmt->pStmt); | |
| 1578 | + assert(NULL != colNamesV); | |
| 1579 | + cson_value_add_reference(colNamesV); | |
| 1580 | + colNames = cson_value_get_array(colNamesV); | |
| 1581 | + assert(NULL != colNames); | |
| 1582 | + } | |
| 1580 | 1583 | row = cson_sqlite3_row_to_object2(pStmt->pStmt, colNames); |
| 1581 | 1584 | if(!row && !warnMsg){ |
| 1582 | 1585 | warnMsg = "Could not convert at least one result row to JSON."; |
| 1583 | 1586 | continue; |
| 1584 | 1587 | } |
| @@ -1589,13 +1592,11 @@ | ||
| 1589 | 1592 | cson_value_free(v); |
| 1590 | 1593 | } |
| 1591 | 1594 | return NULL; |
| 1592 | 1595 | } |
| 1593 | 1596 | } |
| 1594 | - if( colNamesV ){ | |
| 1595 | - cson_value_free(colNamesV); | |
| 1596 | - } | |
| 1597 | + cson_value_free(colNamesV); | |
| 1597 | 1598 | if(warnMsg){ |
| 1598 | 1599 | json_warn( FSL_JSON_W_ROW_TO_JSON_FAILED, warnMsg ); |
| 1599 | 1600 | } |
| 1600 | 1601 | return v; |
| 1601 | 1602 | } |
| @@ -1669,10 +1670,23 @@ | ||
| 1669 | 1670 | } |
| 1670 | 1671 | free(tags); |
| 1671 | 1672 | } |
| 1672 | 1673 | return v; |
| 1673 | 1674 | } |
| 1675 | + | |
| 1676 | +/* | |
| 1677 | + ** Returns a "new" value representing the boolean value of zVal | |
| 1678 | + ** (false if zVal is NULL). Note that cson does not really allocate | |
| 1679 | + ** any memory for boolean values, but they "should" (for reasons of | |
| 1680 | + ** style and philosophy) be cleaned up like any other values (but | |
| 1681 | + ** it's a no-op for bools). | |
| 1682 | + */ | |
| 1683 | +cson_value * json_value_to_bool(cson_value const * zVal){ | |
| 1684 | + return cson_value_get_bool(zVal) | |
| 1685 | + ? cson_value_true() | |
| 1686 | + : cson_value_false(); | |
| 1687 | +} | |
| 1674 | 1688 | |
| 1675 | 1689 | /* |
| 1676 | 1690 | ** Impl of /json/resultCodes |
| 1677 | 1691 | ** |
| 1678 | 1692 | */ |
| 1679 | 1693 |
| --- src/json.c | |
| +++ src/json.c | |
| @@ -1567,18 +1567,21 @@ | |
| 1567 | while( (SQLITE_ROW==db_step(pStmt)) ){ |
| 1568 | cson_value * row = NULL; |
| 1569 | if(!a){ |
| 1570 | if(!v){ |
| 1571 | v = cson_value_new_array(); |
| 1572 | colNamesV = cson_sqlite3_column_names(pStmt->pStmt); |
| 1573 | assert(NULL != colNamesV); |
| 1574 | colNames = cson_value_get_array(colNamesV); |
| 1575 | assert(NULL != colNames); |
| 1576 | } |
| 1577 | a = cson_value_get_array(v); |
| 1578 | assert(NULL!=a); |
| 1579 | } |
| 1580 | row = cson_sqlite3_row_to_object2(pStmt->pStmt, colNames); |
| 1581 | if(!row && !warnMsg){ |
| 1582 | warnMsg = "Could not convert at least one result row to JSON."; |
| 1583 | continue; |
| 1584 | } |
| @@ -1589,13 +1592,11 @@ | |
| 1589 | cson_value_free(v); |
| 1590 | } |
| 1591 | return NULL; |
| 1592 | } |
| 1593 | } |
| 1594 | if( colNamesV ){ |
| 1595 | cson_value_free(colNamesV); |
| 1596 | } |
| 1597 | if(warnMsg){ |
| 1598 | json_warn( FSL_JSON_W_ROW_TO_JSON_FAILED, warnMsg ); |
| 1599 | } |
| 1600 | return v; |
| 1601 | } |
| @@ -1669,10 +1670,23 @@ | |
| 1669 | } |
| 1670 | free(tags); |
| 1671 | } |
| 1672 | return v; |
| 1673 | } |
| 1674 | |
| 1675 | /* |
| 1676 | ** Impl of /json/resultCodes |
| 1677 | ** |
| 1678 | */ |
| 1679 |
| --- src/json.c | |
| +++ src/json.c | |
| @@ -1567,18 +1567,21 @@ | |
| 1567 | while( (SQLITE_ROW==db_step(pStmt)) ){ |
| 1568 | cson_value * row = NULL; |
| 1569 | if(!a){ |
| 1570 | if(!v){ |
| 1571 | v = cson_value_new_array(); |
| 1572 | } |
| 1573 | a = cson_value_get_array(v); |
| 1574 | assert(NULL!=a); |
| 1575 | } |
| 1576 | if(!colNames){ |
| 1577 | colNamesV = cson_sqlite3_column_names(pStmt->pStmt); |
| 1578 | assert(NULL != colNamesV); |
| 1579 | cson_value_add_reference(colNamesV); |
| 1580 | colNames = cson_value_get_array(colNamesV); |
| 1581 | assert(NULL != colNames); |
| 1582 | } |
| 1583 | row = cson_sqlite3_row_to_object2(pStmt->pStmt, colNames); |
| 1584 | if(!row && !warnMsg){ |
| 1585 | warnMsg = "Could not convert at least one result row to JSON."; |
| 1586 | continue; |
| 1587 | } |
| @@ -1589,13 +1592,11 @@ | |
| 1592 | cson_value_free(v); |
| 1593 | } |
| 1594 | return NULL; |
| 1595 | } |
| 1596 | } |
| 1597 | cson_value_free(colNamesV); |
| 1598 | if(warnMsg){ |
| 1599 | json_warn( FSL_JSON_W_ROW_TO_JSON_FAILED, warnMsg ); |
| 1600 | } |
| 1601 | return v; |
| 1602 | } |
| @@ -1669,10 +1670,23 @@ | |
| 1670 | } |
| 1671 | free(tags); |
| 1672 | } |
| 1673 | return v; |
| 1674 | } |
| 1675 | |
| 1676 | /* |
| 1677 | ** Returns a "new" value representing the boolean value of zVal |
| 1678 | ** (false if zVal is NULL). Note that cson does not really allocate |
| 1679 | ** any memory for boolean values, but they "should" (for reasons of |
| 1680 | ** style and philosophy) be cleaned up like any other values (but |
| 1681 | ** it's a no-op for bools). |
| 1682 | */ |
| 1683 | cson_value * json_value_to_bool(cson_value const * zVal){ |
| 1684 | return cson_value_get_bool(zVal) |
| 1685 | ? cson_value_true() |
| 1686 | : cson_value_false(); |
| 1687 | } |
| 1688 | |
| 1689 | /* |
| 1690 | ** Impl of /json/resultCodes |
| 1691 | ** |
| 1692 | */ |
| 1693 |