Skip to content

Commit 03bf13c

Browse files
committed
Add and use our own ASCII routines
`std::tolower` and `std::toupper` are locale-dependent and should not be used anywhere we currently use them. Adds and switches to our own implementations for these and other locale-dependent functions.
1 parent 9616e95 commit 03bf13c

14 files changed

+137
-58
lines changed

src/ast.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
#include "sass.hpp"
44

55
#include "ast.hpp"
6-
#include <cctype>
7-
#include <locale>
86

97
namespace Sass {
108

src/ast_selectors.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -652,15 +652,17 @@ namespace Sass {
652652
CssMediaQuery_Obj CssMediaQuery::merge(CssMediaQuery_Obj& other)
653653
{
654654

655-
std::string ourType(this->type());
656-
std::string theirType(other->type());
657-
std::string ourModifier(this->modifier());
658-
std::string theirModifier(other->modifier());
659-
660-
std::transform(ourType.begin(), ourType.end(), ourType.begin(), ::tolower);
661-
std::transform(theirType.begin(), theirType.end(), theirType.begin(), ::tolower);
662-
std::transform(ourModifier.begin(), ourModifier.end(), ourModifier.begin(), ::tolower);
663-
std::transform(theirModifier.begin(), theirModifier.end(), theirModifier.begin(), ::tolower);
655+
std::string ourType = this->type();
656+
Util::ascii_str_tolower(&ourType);
657+
658+
std::string theirType = other->type();
659+
Util::ascii_str_tolower(&theirType);
660+
661+
std::string ourModifier = this->modifier();
662+
Util::ascii_str_tolower(&ourModifier);
663+
664+
std::string theirModifier = other->modifier();
665+
Util::ascii_str_tolower(&theirModifier);
664666

665667
std::string type;
666668
std::string modifier;

src/color_maps.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "ast.hpp"
66
#include "color_maps.hpp"
7+
#include "util_string.hpp"
78

89
namespace Sass {
910

@@ -616,8 +617,8 @@ namespace Sass {
616617
const Color_RGBA* name_to_color(const std::string& key)
617618
{
618619
// case insensitive lookup. See #2462
619-
std::string lower{key};
620-
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
620+
std::string lower = key;
621+
Util::ascii_str_tolower(&lower);
621622

622623
auto p = names_to_colors->find(lower);
623624
if (p != names_to_colors->end()) {

src/file.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#else
1414
# include <unistd.h>
1515
#endif
16-
#include <cctype>
1716
#include <cstdio>
1817
#include <vector>
1918
#include <algorithm>
@@ -25,6 +24,7 @@
2524
#include "sass_functions.hpp"
2625
#include "error_handling.hpp"
2726
#include "util.hpp"
27+
#include "util_string.hpp"
2828
#include "sass2scss.h"
2929

3030
#ifdef _WIN32
@@ -106,13 +106,13 @@ namespace Sass {
106106
bool is_absolute_path(const std::string& path)
107107
{
108108
#ifdef _WIN32
109-
if (path.length() >= 2 && isalpha(path[0]) && path[1] == ':') return true;
109+
if (path.length() >= 2 && Util::ascii_isalpha(path[0]) && path[1] == ':') return true;
110110
#endif
111111
size_t i = 0;
112112
// check if we have a protocol
113-
if (path[i] && Prelexer::is_alpha(path[i])) {
113+
if (path[i] && Util::ascii_isalpha(static_cast<unsigned char>(path[i]))) {
114114
// skip over all alphanumeric characters
115-
while (path[i] && Prelexer::is_alnum(path[i])) ++i;
115+
while (path[i] && Util::ascii_isalnum(static_cast<unsigned char>(path[i]))) ++i;
116116
i = i && path[i] == ':' ? i + 1 : 0;
117117
}
118118
return path[i] == '/';
@@ -179,9 +179,9 @@ namespace Sass {
179179

180180
size_t proto = 0;
181181
// check if we have a protocol
182-
if (path[proto] && Prelexer::is_alpha(path[proto])) {
182+
if (path[proto] && Util::ascii_isalpha(static_cast<unsigned char>(path[proto]))) {
183183
// skip over all alphanumeric characters
184-
while (path[proto] && Prelexer::is_alnum(path[proto++])) {}
184+
while (path[proto] && Util::ascii_isalnum(static_cast<unsigned char>(path[proto++]))) {}
185185
// then skip over the mandatory colon
186186
if (proto && path[proto] == ':') ++ proto;
187187
}
@@ -260,9 +260,9 @@ namespace Sass {
260260

261261
size_t proto = 0;
262262
// check if we have a protocol
263-
if (path[proto] && Prelexer::is_alpha(path[proto])) {
263+
if (path[proto] && Util::ascii_isalpha(static_cast<unsigned char>(path[proto]))) {
264264
// skip over all alphanumeric characters
265-
while (path[proto] && Prelexer::is_alnum(path[proto++])) {}
265+
while (path[proto] && Util::ascii_isalnum(static_cast<unsigned char>(path[proto++]))) {}
266266
// then skip over the mandatory colon
267267
if (proto && path[proto] == ':') ++ proto;
268268
}
@@ -288,7 +288,8 @@ namespace Sass {
288288
#else
289289
// compare the charactes in a case insensitive manner
290290
// windows fs is only case insensitive in ascii ranges
291-
if (tolower(abs_path[i]) != tolower(abs_base[i])) break;
291+
if (Util::ascii_tolower(static_cast<unsigned char>(abs_path[i])) !=
292+
Util::ascii_tolower(static_cast<unsigned char>(abs_base[i]))) break;
292293
#endif
293294
if (abs_path[i] == '/') index = i + 1;
294295
}
@@ -488,8 +489,7 @@ namespace Sass {
488489
if (path.length() > 5) {
489490
extension = path.substr(path.length() - 5, 5);
490491
}
491-
for(size_t i=0; i<extension.size();++i)
492-
extension[i] = tolower(extension[i]);
492+
Util::ascii_str_tolower(&extension);
493493
if (extension == ".sass" && contents != 0) {
494494
char * converted = sass2scss(contents, SASS2SCSS_PRETTIFY_1 | SASS2SCSS_KEEP_COMMENT);
495495
free(contents); // free the indented contents

src/fn_colors.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
// __EXTENSIONS__ fix on Solaris.
33
#include "sass.hpp"
44

5-
#include <cctype>
65
#include <iomanip>
76
#include "ast.hpp"
87
#include "fn_utils.hpp"
98
#include "fn_colors.hpp"
109
#include "util.hpp"
10+
#include "util_string.hpp"
1111

1212
namespace Sass {
1313

@@ -582,10 +582,8 @@ namespace Sass {
582582
ss << std::hex << std::setw(2) << static_cast<unsigned long>(Sass::round(g, ctx.c_options.precision));
583583
ss << std::hex << std::setw(2) << static_cast<unsigned long>(Sass::round(b, ctx.c_options.precision));
584584

585-
std::string result(ss.str());
586-
for (size_t i = 0, L = result.length(); i < L; ++i) {
587-
result[i] = std::toupper(result[i]);
588-
}
585+
std::string result = ss.str();
586+
Util::ascii_str_toupper(&result);
589587
return SASS_MEMORY_NEW(String_Quoted, pstate, result);
590588
}
591589

src/fn_numbers.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include <cstdint>
66
#include <cstdlib>
77
#include <cmath>
8-
#include <cctype>
98
#include <random>
109
#include <sstream>
1110
#include <iomanip>

src/fn_strings.cpp

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
// __EXTENSIONS__ fix on Solaris.
33
#include "sass.hpp"
44

5-
#include <cctype>
65
#include "utf8.h"
76
#include "ast.hpp"
87
#include "fn_utils.hpp"
98
#include "fn_strings.hpp"
9+
#include "util_string.hpp"
1010

1111
namespace Sass {
1212

@@ -212,12 +212,7 @@ namespace Sass {
212212
{
213213
String_Constant* s = ARG("$string", String_Constant);
214214
std::string str = s->value();
215-
216-
for (size_t i = 0, L = str.length(); i < L; ++i) {
217-
if (Sass::Util::isAscii(str[i])) {
218-
str[i] = std::toupper(str[i]);
219-
}
220-
}
215+
Util::ascii_str_toupper(&str);
221216

222217
if (String_Quoted* ss = Cast<String_Quoted>(s)) {
223218
String_Quoted* cpy = SASS_MEMORY_COPY(ss);
@@ -233,12 +228,7 @@ namespace Sass {
233228
{
234229
String_Constant* s = ARG("$string", String_Constant);
235230
std::string str = s->value();
236-
237-
for (size_t i = 0, L = str.length(); i < L; ++i) {
238-
if (Sass::Util::isAscii(str[i])) {
239-
str[i] = std::tolower(str[i]);
240-
}
241-
}
231+
Util::ascii_str_tolower(&str);
242232

243233
if (String_Quoted* ss = Cast<String_Quoted>(s)) {
244234
String_Quoted* cpy = SASS_MEMORY_COPY(ss);

src/lexer.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// __EXTENSIONS__ fix on Solaris.
33
#include "sass.hpp"
44

5-
#include <cctype>
65
#include <iostream>
76
#include <iomanip>
87
#include "lexer.hpp"

src/prelexer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
// __EXTENSIONS__ fix on Solaris.
33
#include "sass.hpp"
44

5-
#include <cctype>
65
#include <iostream>
76
#include <iomanip>
87
#include "util.hpp"
8+
#include "util_string.hpp"
99
#include "position.hpp"
1010
#include "prelexer.hpp"
1111
#include "constants.hpp"
@@ -1400,7 +1400,7 @@ namespace Sass {
14001400
}*/
14011401

14021402
const char* H(const char* src) {
1403-
return std::isxdigit(static_cast<unsigned char>(*src)) ? src+1 : 0;
1403+
return Util::ascii_isxdigit(static_cast<unsigned char>(*src)) ? src+1 : 0;
14041404
}
14051405

14061406
const char* W(const char* src) {

src/util.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "sass.h"
33
#include "ast.hpp"
44
#include "util.hpp"
5+
#include "util_string.hpp"
56
#include "lexer.hpp"
67
#include "prelexer.hpp"
78
#include "constants.hpp"
@@ -289,7 +290,7 @@ namespace Sass {
289290

290291
// parse as many sequence chars as possible
291292
// ToDo: Check if ruby aborts after possible max
292-
while (i + len < L && s[i + len] && isxdigit(s[i + len])) ++ len;
293+
while (i + len < L && s[i + len] && Util::ascii_isxdigit(static_cast<unsigned char>(s[i + len]))) ++ len;
293294

294295
if (len > 1) {
295296

@@ -375,7 +376,7 @@ namespace Sass {
375376

376377
// parse as many sequence chars as possible
377378
// ToDo: Check if ruby aborts after possible max
378-
while (i + len < L && s[i + len] && isxdigit(s[i + len])) ++ len;
379+
while (i + len < L && s[i + len] && Util::ascii_isxdigit(static_cast<unsigned char>(s[i + len]))) ++ len;
379380

380381
// hex string?
381382
if (keep_utf8_sequences) {
@@ -718,9 +719,5 @@ namespace Sass {
718719
return false;
719720
}
720721

721-
bool isAscii(const char chr) {
722-
return unsigned(chr) < 128;
723-
}
724-
725722
}
726723
}

0 commit comments

Comments
 (0)