Script-Fu get-output-string cuts a list of symbols read as a string at the 256th char
Environment/Versions
- GIMP version: 2.10.34
-
C:\Program Files\GIMP 2\lib\gimp\2.0\plug-ins\script-fu\
script-fu.exe on Monday, February 27, 2023 6:27:06 PM - Operating System: Windows 10
Description of the bug
Reproduction
Is the bug reproducible? Always
Reproduction steps:
- Gimp menu "Filters" > "Script-Fu" > "Console" (Alt+R S C)
- In the Script-Fu console, copy and paste the following Scheme expression:
(let* ( (nbrChar 250) (lstSymb (list (string->symbol (make-string nbrChar #\A)) 'bugCut 'in '2nd 'symbol)) ; list of symbols
(pos (open-output-string)) (sts (write lstSymb pos)) (strRes (get-output-string pos))
) ; writing port pos is OK. ^ Forgets the 3 chars of "Cut": KO
(close-output-port pos)(display "sts: ")(display sts)
(display " strRes: \"")(display (substring strRes nbrChar))(display "\" length: ")(display (string-length strRes))
)
#<EOF>
could be displayed.
Actual result:
sts: #t strRes: "A bug in 2nd symbol)" length: 270#t
Expected result
sts: #t strRes: "A bugCut in 2nd symbol)" length: 273#t
Click to reproduce the expected result?
The expected result is displayed after writing the same list of symbols lstSymb
in the text file test.txt read in User's Gimp script folder:
(let* ( (nbrChar 250) (lstSymb (list (string->symbol (make-string nbrChar #\A)) 'bugCut 'in '2nd 'symbol))
(fileTst (string-append gimp-directory DIR-SEPARATOR "scripts" DIR-SEPARATOR "test.txt")) ; 273 bytes: OK
(pof (open-output-file fileTst)) (sts (and (write lstSymb pof) (newline pof))) (closingPof (close-output-port pof))
(readFirstLine (lambda(portin) ; Read the line until the first carriage-return or EOF
(let loop ((ch (read-char portin)) (strRead ""))
(if (or (eof-object? ch) (char=? ch #\newline)) strRead
(loop (read-char portin) (string-append strRead (string ch)))
) ) ) )
(pif (open-input-file fileTst)) (strRes (readFirstLine pif)) (closingPif (close-input-port pif))
) ; This reader reads 273 chars: OK. So 3 more chars than get-output-string
(map display (list "sts: " sts " strRes: \"" (substring strRes nbrChar) "\" length: " (string-length strRes))) #t
)
Note that the simplified reader readFirstLine
of test.txt is supplied because there is not read-line
in script-fu.init or script-fu-compat.init
Alternatively, the generated test.txt could be analyzed in any text editors such as Notepad++.
Additional information
Replacing the list of symbols lstSymb
with the list of string lstStr
shows that get-output-string
works fine with a list of strings.
(let* ( (nbrChar 250) (lstStr (list (make-string nbrChar #\A) "bugCut" "is NOT found with a list of strings")) ; OK
(pos (open-output-string)) (sts (write lstStr pos)) (strRes (get-output-string pos))
)
(close-output-port pos)(display "sts: ")(display sts)
(display " strRes: \"")(display (substring strRes nbrChar))(display "\" length: ")(display (string-length strRes))
)
will display:
sts: #t strRes: "AA" "bugCut" "is NOT found with a list of strings\")" length: 301#t
get-output-string
seems to fail when the list of symbols transformed as a string is beyond the length of 256 characters:
-
For the sake of simplicity, the first symbol of
lstSymb
is generated from a long string ofnbrChar
=250
character#\A
= the letter "A".This item of list can be replaced with several shorter symbols if, once --concatenated in a string--, the sum of their lengths should be around 250.
-
The issue could be located processing the second symbol
'bugCut
with the threshold of the 256th char between "bug" and "Cut".Everything after the three letters "bug" such as "
Cut" or "Cute" are lost. -
However, the issue does not affect others items such as
'in '2nd 'symbol
.
Conclusion
Maybe, the get-output-string
issue about a list of symbols read as a string could be relative to a buffer overflow around the 256th character in Script-Fu plug-in.