diff options
author | lains <lains@caramail.com> | 2019-09-22 17:33:56 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-09-22 17:33:56 +0200 |
commit | bb680f70f18f1200bdc25b45031e26ac07c71979 (patch) | |
tree | ade0e3a07b26f4aae2f4e64be5fe35afc828fe6b /navit/util.c | |
parent | deccb6c4379e135ae45513a7bfef3b4998f24e94 (diff) | |
download | navit-bb680f70f18f1200bdc25b45031e26ac07c71979.tar.gz |
Add/Android: Provide geo coordinates for clicked position in contextual menu (#794)
* Adding unescape string utility and unescaping alls values in textfile attributes
* Moving coordinates_geo out of internal use in gui_internal_command.c (to coord.c)
* Moving gui_internal_escape() into generic str_escape() function in util.c
* Moving strncpy_unescape() into generic function in util.c
* Using geo coords as item name in Android contextual menu "Route Here"
* Using string escaping (for double quotes) when writing former destinations to file
* Adding new type DEGREES_MINUTES_SECONDS_BRIEF to factorize coordinates_geo()
And fixing the example strings to match what is actually output by the function
* Adding support for DEGREES_MINUTES_SECONDS_BRIEF format into coord_format
And add internal coord_format_with_sep() to specify the separator
* Fixing doxygen doc for coord_format_with_sep()
* Making coord_format() inline
* Using new factorized generic function coord_geo_format_short() instead of coordinates_geo()
* Changing single contextual window title with GPS coords on Android
* Adding string bytes length for each coord to string format, using short format in pcoord_format_short() and coord_geo_format_short()
* Using pcoord_format_short() in android
Diffstat (limited to 'navit/util.c')
-rw-r--r-- | navit/util.c | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/navit/util.c b/navit/util.c index 944dc2a21..cf4412938 100644 --- a/navit/util.c +++ b/navit/util.c @@ -114,6 +114,129 @@ static void strtrim(char *s) { } /** + * @brief Escape special characters from a string + * + * @param mode The escape mode that needs to be enabled (see enum escape_mode) + * @param in The string to escape + * + * @return The escaped string + * + * @note In html escape mode (escape_mode_html), we will only process HTML escape sequence, and string quoting, but we won't escape backslashes or double quotes + * @warning The returned string has been allocated and g_free() must thus be called on this string + */ +char *str_escape(enum escape_mode mode, const char *in) { + int len=mode & escape_mode_string ? 2:0; /* Add 2 characters to the length of the buffer if quoting is enabled */ + char *dst,*out; + const char *src=in; + static const char *quot="""; + static const char *apos="'"; + static const char *amp="&"; + static const char *lt="<"; + static const char *gt=">"; + + dbg(lvl_debug, "Will escape string=\"%s\", escape mode %d", in, mode); + while (*src) { + if ((*src == '"' || *src == '\\') && (mode & (escape_mode_string | escape_mode_quote))) + len++; + if (*src == '"' && mode == escape_mode_html_quote) + len+=strlen(quot); + else if (*src == '\'' && mode == escape_mode_html_apos) + len+=strlen(apos); + else if (*src == '&' && mode == escape_mode_html_amp) + len+=strlen(amp); + else if (*src == '<' && mode == escape_mode_html_lt) + len+=strlen(lt); + else if (*src == '>' && mode == escape_mode_html_gt) + len+=strlen(gt); + else + len++; + src++; + } + src=in; + out=dst=g_malloc(len+1); /* +1 character for NUL termination */ + + /* In string quoting mode (escape_mode_string), prepend the whole string with a double quote */ + if (mode & escape_mode_string) + *dst++='"'; + + while (*src) { + if (mode & escape_mode_html) { /* In html escape mode, only process HTML escape sequence, not backslashes or quotes */ + if (*src == '"' && (mode & escape_mode_html_quote)) { + strcpy(dst,quot); + src++; + dst+=strlen(quot); + } else if (*src == '\'' && (mode & escape_mode_html_apos)) { + strcpy(dst,apos); + src++; + dst+=strlen(apos); + } else if (*src == '&' && (mode & escape_mode_html_amp)) { + strcpy(dst,amp); + src++; + dst+=strlen(amp); + } else if (*src == '<' && (mode & escape_mode_html_lt)) { + strcpy(dst,lt); + src++; + dst+=strlen(lt); + } else if (*src == '>' && (mode & escape_mode_html_gt)) { + strcpy(dst,gt); + src++; + dst+=strlen(gt); + } else + *dst++=*src++; + } else { + if ((*src == '"' || *src == '\\') && (mode & (escape_mode_string | escape_mode_quote))) { + *dst++='\\'; + } + *dst++=*src++; + } + } + + /* In string quoting mode (escape_mode_string), append a double quote to the whole string */ + if (mode & escape_mode_string) + *dst++='"'; + + *dst++='\0'; + dbg(lvl_debug, "Result of escaped string=\"%s\"", out); + return out; +} + +/** + * @brief Copy a string from @p src to @p dest, unescaping characters + * + * @note Escaped characters are "\\\\" (double backslash) resulting in '\\' (single backslash) + * and "\\\"" (backslash followed by double quote), resulting in '"' (double quote) + * but we will escape any other character, for example "\\ " will result in ' ' (space) + * This is the reverse of function str_escape, except that we assume (and only support) unescaping mode escape_mode_quote here + * + * @param[out] dest The location where to store the unescaped string + * @param[in] src The source string to copy (and to unescape) + * @param n The maximum amount of bytes copied into dest. Warning: If there is no null byte among the n bytes written to dest, the string placed in dest will not be null-terminated. + * + * @return A pointer to the destination string @p dest + */ +char *strncpy_unescape(char *dest, const char *src, size_t n) { + char *dest_ptr; /* A pointer to the currently parsed character inside string dest */ + + for (dest_ptr=dest; (dest_ptr-dest) < n && (*src != '\0'); src++, dest_ptr++) { + if (*src == '\\') { + src++; + } + *dest_ptr = *src; + if (*dest_ptr == '\0') { + /* This is only possible if we just parsed an escaped sequence '\\' followed by a NUL termination, which is not really sane, but we will silently accept this case */ + return dest; + } + } + if ((dest_ptr-dest) < n) + *dest_ptr='\0'; /* Add a trailing '\0' if any room is remaining */ + else { + // strncpy_unescape will return a non NUL-terminated string. Trouble ahead if this is not handled properly + } + + return dest; +} + +/** * @brief Parser states for `parse_for_systematic_comparison()`. */ enum parse_state { |