]>
Commit | Line | Data |
---|---|---|
d8f20e85 | 1 | /* |
0545caaa | 2 | * Copyright (C) 1996-2014 The Squid Software Foundation and contributors |
d8f20e85 | 3 | * |
0545caaa AJ |
4 | * Squid software is distributed under GPLv2+ license and includes |
5 | * contributions from numerous individuals and organizations. | |
6 | * Please see the COPYING and CONTRIBUTORS files for details. | |
d8f20e85 | 7 | */ |
8 | ||
f7f3304a | 9 | #include "squid.h" |
25f98340 | 10 | #include "html_quote.h" |
d8f20e85 | 11 | |
d8f20e85 | 12 | #if HAVE_STRING_H |
13 | #include <string.h> | |
14 | #endif | |
15 | ||
26ac0430 | 16 | /* |
d8f20e85 | 17 | * HTML defines these characters as special entities that should be quoted. |
18 | */ | |
19 | static struct { | |
20 | unsigned char code; | |
e016fecf | 21 | const char *quote; |
d8f20e85 | 22 | } htmlstandardentities[] = |
23 | ||
24 | { | |
25 | /* NOTE: The quoted form MUST not be larger than 6 character. | |
26 | * see close to the MemPool commend below | |
27 | */ | |
28 | { | |
26ac0430 | 29 | '<', "<" |
d8f20e85 | 30 | }, |
31 | { | |
26ac0430 | 32 | '>', ">" |
d8f20e85 | 33 | }, |
34 | { | |
26ac0430 | 35 | '"', """ |
d8f20e85 | 36 | }, |
37 | { | |
26ac0430 | 38 | '&', "&" |
d8f20e85 | 39 | }, |
40 | { | |
26ac0430 | 41 | '\'', "'" |
d8f20e85 | 42 | }, |
43 | { | |
26ac0430 | 44 | 0, NULL |
d8f20e85 | 45 | } |
46 | }; | |
47 | ||
48 | /* | |
26ac0430 | 49 | * html_do_quote - Returns a static buffer containing the quoted |
d8f20e85 | 50 | * string. |
51 | */ | |
52 | char * | |
53 | html_quote(const char *string) | |
54 | { | |
55 | static char *buf; | |
56 | static size_t bufsize = 0; | |
57 | const char *src; | |
58 | char *dst; | |
59 | int i; | |
60 | ||
61 | /* XXX This really should be implemented using a MemPool, but | |
62 | * MemPools are not yet available in lib... | |
63 | */ | |
64 | if (buf == NULL || strlen(string) * 6 > bufsize) { | |
26ac0430 AJ |
65 | xfree(buf); |
66 | bufsize = strlen(string) * 6 + 1; | |
67 | buf = xcalloc(bufsize, 1); | |
d8f20e85 | 68 | } |
69 | for (src = string, dst = buf; *src; src++) { | |
26ac0430 AJ |
70 | const char *escape = NULL; |
71 | const unsigned char ch = *src; | |
d8f20e85 | 72 | |
26ac0430 AJ |
73 | /* Walk thru the list of HTML Entities that must be quoted to |
74 | * display safely | |
75 | */ | |
76 | for (i = 0; htmlstandardentities[i].code; i++) { | |
77 | if (ch == htmlstandardentities[i].code) { | |
78 | escape = htmlstandardentities[i].quote; | |
79 | break; | |
80 | } | |
81 | } | |
82 | /* Encode control chars just to be on the safe side, and make | |
83 | * sure all 8-bit characters are encoded to protect from buggy | |
84 | * clients | |
85 | */ | |
86 | if (!escape && (ch <= 0x1F || ch >= 0x7f) && ch != '\n' && ch != '\r' && ch != '\t') { | |
87 | static char dec_encoded[7]; | |
88 | snprintf(dec_encoded, sizeof dec_encoded, "&#%3d;", (int) ch); | |
89 | escape = dec_encoded; | |
90 | } | |
91 | if (escape) { | |
92 | /* Ok, An escaped form was found above. Use it */ | |
93 | strncpy(dst, escape, 6); | |
94 | dst += strlen(escape); | |
95 | } else { | |
96 | /* Apparently there is no need to escape this character */ | |
97 | *dst++ = ch; | |
98 | } | |
d8f20e85 | 99 | } |
100 | /* Nullterminate and return the result */ | |
101 | *dst = '\0'; | |
102 | return (buf); | |
103 | } |