Enforce the --charlimit constraint in QRF.

FossilOrigin-Name: c25f8fdedd8d68e3551a445e24e1c60e105e18f9cf8f1badcbb77a58974f3381
This commit is contained in:
drh
2025-11-14 21:40:20 +00:00
parent 9a3561e2d9
commit c2b9896e50
5 changed files with 84 additions and 19 deletions
+6 -10
View File
@@ -298,15 +298,11 @@ If the sqlite3_qrf_spec.nCharLimit setting is non-zero, then the formatter
will display only the first nCharLimit characters of each value.
Only characters that take up space are counted when enforcing this
limit. Zero-width characters and VT100 escape sequences do not count
toward this limit. The count is in characters, not bytes.
Content length limits only apply to TEXT and BLOB values. Numeric
values and NULLs always display their full text regardless of the
nCharLimit setting.
*This setting is a place-holder.
As for 2025-11-07, the nCharLimit constraint is not yet implemented.
The current behavior is always as if nCharLimit where zero.*
toward this limit. The count is in characters, not bytes. When
imposing this limit, the formatter adds the three characters "..."
to the end of the value. Those added characters are not counted
as part of the limit. Very small limits still result in truncation,
but might render a few more characters than the limit.
If the sqlite3_qrf_spec.nLineLimit setting is non-zero, then the
formatter will only display the first nLineLimit lines of each value.
@@ -315,7 +311,7 @@ character, or if it split by wrapping. This setting merely limits
the number of displayed lines. This setting only works for
**Box**, **Column**, **Line**, **Markdown**, and **Table** styles.
The idea behind these settings is to prevent excessively large renderings
The idea behind both of these settings is to prevent large renderings
when doing a query that (unexpectedly) contains very large text or
blob values: perhaps megabyes of text.
+39
View File
@@ -859,6 +859,9 @@ static const char *qrfJsonbToJson(Qrf *p, int iCol){
** Render value pVal into pOut
*/
static void qrfRenderValue(Qrf *p, sqlite3_str *pOut, int iCol){
#if SQLITE_VERSION_NUMBER>=3052000
int iStartLen = sqlite3_str_length(pOut);
#endif
if( p->spec.xRender ){
sqlite3_value *pVal;
char *z;
@@ -969,6 +972,42 @@ static void qrfRenderValue(Qrf *p, sqlite3_str *pOut, int iCol){
break;
}
}
#if SQLITE_VERSION_NUMBER>=3052000
if( p->spec.nCharLimit>0
&& (sqlite3_str_length(pOut) - iStartLen) > p->spec.nCharLimit
){
const unsigned char *z;
int ii = 0, w = 0, limit = p->spec.nCharLimit;
z = (const unsigned char*)sqlite3_str_value(pOut) + iStartLen;
if( limit<4 ) limit = 4;
while( 1 ){
if( z[ii]<' ' ){
int k;
if( z[ii]=='\033' && (k = qrfIsVt100(z+ii))>0 ){
ii += k;
}else if( z[ii]==0 ){
break;
}else{
ii++;
}
}else if( (0x80&z[ii])==0 ){
w++;
if( w>limit ) break;
ii++;
}else{
int u = 0;
int len = sqlite3_qrf_decode_utf8(&z[ii], &u);
w += sqlite3_qrf_wcwidth(u);
if( w>limit ) break;
ii += len;
}
}
if( w>limit ){
sqlite3_str_truncate(pOut, iStartLen+ii);
sqlite3_str_append(pOut, "...", 3);
}
}
#endif
}
/*