SQLite Forum

a probable bug in .output handler
Login

a probable bug in .output handler

(1) By Larry Brasfield (LarryBrasfield) on 2020-04-23 20:15:46 [source]

In the handler for .output, .once and .excel commands, (in today's 202004221349.tar.gz preview and also at line 8349 in shell.c.in), a local variable bOnce is introduced, without initialization. It appears that when the .output command is handled by this code, bOnce remains uninitialized until its first use at line 8385 in a conditional. The MSVC v19 compiler warns of this, and I think it is right to do so. I think the code is bound to fail for the .output command whenever the stack does not happen to contain 0 where bOnce is allocated.

I have to say that this code is immensely more readable than before. I doubt I would be able to make this claim of incorrectness before, at least not without a lot more study.

(2) By Richard Hipp (drh) on 2020-04-23 20:49:11 [link] [source] in reply to 1

Thanks. Fixed by check-in 65c6c26bb48d5347, I think.

(3) By Larry Brasfield (LarryBrasfield) on 2020-04-24 03:38:31 [link] [source] in reply to 2

I'm not sure it's "fixed" in the usual sense, but it works with the initializer. (I tested .output, .once, and .excel with combinations of options and named FILE.)

For grins, I tested with and without bOnce initialized to zero. It seems to work the same way, regardless. I would have to run it under a debugger to see why, but it seems not worth the bother. (The behavior is undefined, after all.)

While testing I noticed something contrary to expectation. The help for .once suggests that, if a FILE is named, that's were the re-routed output will go. But with the -x option given, a tempfile is created regardless. (I discovered this because I forgot what names I had used, and went to see what got written. Only then did I see that when Excel opens, the title bar shows one of the bizarre filenames that gets generated for tempfiles.) I suppose a separate report on that would be appropriate.

(4) By Richard Hipp (drh) on 2020-04-24 13:19:11 [link] [source] in reply to 3

The help for .once suggests that, if a FILE is named, that's were the re-routed output will go. But with the -x option given, a tempfile is created regardless.

The help text in the CLI strives to obtain a balance between brevity and completeness. Your concrete suggestions on how to better achieve that balance are welcomed.

(5) By Larry Brasfield (LarryBrasfield) on 2020-04-24 15:15:33 [link] [source] in reply to 4

That balance is a challenge, particularly for these redirection commands. Below, I propose replacements for all 3 which capture their behavior and provide some clues for cases when system settings may alter that behavior. (I encountered such difficulty myself, and had to read code to discover why output to a spreadsheet did not work. I was tempted to explain that, on Windows, %COMSPEC% must expand to invoke cmd.exe before -e or -x can work as stated, but that would only benefit those running non-stock shells.)

Present help:

  /*--+----- --------- -----+--+ --------- --------- --------- --------- ----*/
  ".excel                   Display the output of next command in spreadsheet",
  "   --bom                   Put a UTF8 byte-order mark on intermediate file",
...
  ".once ?OPTIONS? ?FILE?   Output for the next SQL command only to FILE",
  "     If FILE begins with '|' then open as a pipe",
  "       --bom  Put a UTF8 byte-order mark at the beginning",
  "       -e     Send output to the system text editor",
  "       -x     Send output as CSV to a spreadsheet (same as \".excel\")",
...
  ".output ?FILE?           Send output to FILE or stdout if FILE is omitted",
  "   If FILE begins with '|' then open it as a pipe.",
  "   Options:",
  "     --bom                 Prefix output with a UTF8 byte-order mark",
  "     -e                    Send output to the system text editor",
  "     -x                    Send output as CSV to a spreadsheet",

Proposed help without functionality changes:

  /*--+----- --------- -----+--+ --------- --------- --------- --------- ----*/
  ".excel ?OPTION?          Next SQL output as .CSV and opened in spreadsheet",
  "   OPTION may be --bom to prefix output with a UTF8 byte-order mark.",
  "   Output is a temp-file with a .csv extension, opened by any program that",
  "   has been designated by the system for such files, often a spreadsheet.",
  /*--+----- --------- -----+--+ --------- --------- --------- --------- ----*/
  ".once ?OPTION? ?SINK?    Output for the next SQL command only goes to SINK",
  "   OPTION may be --bom to prefix output with a UTF8 byte-order mark.",
  "   If SINK begins with '|' then open it as a pipe, else it either names a"
  "   file or is one of the following to produce then process a temp-file:",
  "      -e     Output as .txt and then open in system text editor for .txt",
  "      -x     Output as .CSV then open in spreadsheet (same as \".excel\")",
  /*--+----- --------- -----+--+ --------- --------- --------- --------- ----*/
  ".output ?OPTION? ?SINK?  Output for subsequent SQL commands goes to SINK",
  "   OPTION may be --bom to prefix output with a UTF8 byte-order mark.",
  "   If SINK begins with '|' then open it as a pipe, else it either names a"
  "   file or is one of the following to produce then process a temp-file:",
  "      -e     Output as .txt and then open in system text editor for .txt",
  "      -x     Output as .CSV then open in spreadsheet (same as \".excel\")",
  "   Output is diverted until .output or .once SINK is omitted or \"stdout\"."
  /*--+----- --------- -----+--+ --------- --------- --------- --------- ----*/