Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2020-12-10 05:33:55 +0300
committerCampbell Barton <ideasman42@gmail.com>2020-12-10 06:40:01 +0300
commit7fc1d760378f5c538c44bc4730c98af820678e4d (patch)
tree6980ad22bf2811344c4c4e61610dc173ad2edef5 /source/blender/blenlib/intern
parent65f139117db4aa23f0a59aba788cec843a43b098 (diff)
Fix BLI_str_escape with control characters, add unit tests
Diffstat (limited to 'source/blender/blenlib/intern')
-rw-r--r--source/blender/blenlib/intern/string.c65
1 files changed, 28 insertions, 37 deletions
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index dd120a531fa..4734753d304 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -317,49 +317,40 @@ char *BLI_sprintfN(const char *__restrict format, ...)
return n;
}
-/* match pythons string escaping, assume double quotes - (")
- * TODO: should be used to create RNA animation paths.
- * TODO: support more fancy string escaping. current code is primitive
- * this basically is an ascii version of PyUnicode_EncodeUnicodeEscape()
- * which is a useful reference. */
-size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
+/**
+ * This roughly matches C and Python's string escaping with double quotes - `"`.
+ *
+ * Since every character may need escaping,
+ * it's common to create a buffer twice as large as the input.
+ *
+ * \param dst: The destination string, at least \a dst_maxncpy, typically `(strlen(src) * 2) + 1`.
+ * \param src: The un-escaped source string.
+ * \param dst_maxncpy: The maximum number of bytes allowable to copy.
+ *
+ * \note This is used for creating animation paths in blend files.
+ */
+size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, const size_t dst_maxncpy)
{
- size_t len = 0;
- BLI_assert(maxncpy != 0);
+ BLI_assert(dst_maxncpy != 0);
- while (len < maxncpy) {
- switch (*src) {
- case '\0':
- goto escape_finish;
- case '\\':
- case '"':
- ATTR_FALLTHROUGH;
-
- /* less common but should also be support */
- case '\t':
- case '\n':
- case '\r':
- if (len + 1 < maxncpy) {
- *dst++ = '\\';
- len++;
- }
- else {
- /* not enough space to escape */
- break;
- }
- ATTR_FALLTHROUGH;
- default:
- *dst = *src;
+ size_t len = 0;
+ for (; (len < dst_maxncpy) && (*src != '\0'); dst++, src++, len++) {
+ char c = *src;
+ if (ELEM(c, '\\', '"') || /* Use as-is. */
+ ((c == '\t') && ((void)(c = 't'), true)) || /* Tab. */
+ ((c == '\n') && ((void)(c = 'n'), true)) || /* Newline. */
+ ((c == '\r') && ((void)(c = 'r'), true))) /* Carriage return. */
+ {
+ if (UNLIKELY(len + 1 >= dst_maxncpy)) {
+ /* Not enough space to escape. */
break;
+ }
+ *dst++ = '\\';
+ len++;
}
- dst++;
- src++;
- len++;
+ *dst = c;
}
-
-escape_finish:
-
*dst = '\0';
return len;