summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarti Maria <info@littlecms.com>2016-12-06 22:13:35 +0100
committerMarti Maria <info@littlecms.com>2016-12-06 22:13:50 +0100
commita3def7562bd72961b8dffb1aa601e304952a778c (patch)
tree709d51b767ed8b61782ec5a0c81b047e572eac19
parent422f50dd6e3bff83be6f4b2c6ed0f1a0524abd6d (diff)
downloadlcms2-a3def7562bd72961b8dffb1aa601e304952a778c.tar.gz
non-happy path fixes
Fix leak from named color list error recovery Sanitize maximum string in CGATS parser
-rw-r--r--src/cmscgats.c106
-rw-r--r--src/cmsnamed.c13
2 files changed, 63 insertions, 56 deletions
diff --git a/src/cmscgats.c b/src/cmscgats.c
index a68a84c..5fd80c8 100644
--- a/src/cmscgats.c
+++ b/src/cmscgats.c
@@ -871,7 +871,7 @@ void InSymbol(cmsIT8* it8)
k = 0;
NextCh(it8);
- while (k < MAXSTR && it8->ch != sng) {
+ while (k < (MAXSTR-1) && it8->ch != sng) {
if (it8->ch == '\n'|| it8->ch == '\r') k = MAXSTR+1;
else {
@@ -1944,67 +1944,67 @@ cmsBool HeaderSection(cmsIT8* it8)
case SIDENT:
- strncpy(VarName, it8->id, MAXID-1);
- VarName[MAXID-1] = 0;
+ strncpy(VarName, it8->id, MAXID - 1);
+ VarName[MAXID - 1] = 0;
- if (!IsAvailableOnList(it8-> ValidKeywords, VarName, NULL, &Key)) {
+ if (!IsAvailableOnList(it8->ValidKeywords, VarName, NULL, &Key)) {
#ifdef CMS_STRICT_CGATS
- return SynError(it8, "Undefined keyword '%s'", VarName);
+ return SynError(it8, "Undefined keyword '%s'", VarName);
#else
- Key = AddAvailableProperty(it8, VarName, WRITE_UNCOOKED);
- if (Key == NULL) return FALSE;
+ Key = AddAvailableProperty(it8, VarName, WRITE_UNCOOKED);
+ if (Key == NULL) return FALSE;
#endif
- }
+ }
- InSymbol(it8);
- if (!GetVal(it8, Buffer, MAXSTR-1, "Property data expected")) return FALSE;
+ InSymbol(it8);
+ if (!GetVal(it8, Buffer, MAXSTR - 1, "Property data expected")) return FALSE;
- if(Key->WriteAs != WRITE_PAIR) {
- AddToList(it8, &GetTable(it8)->HeaderList, VarName, NULL, Buffer,
- (it8->sy == SSTRING) ? WRITE_STRINGIFY : WRITE_UNCOOKED);
- }
- else {
- const char *Subkey;
- char *Nextkey;
- if (it8->sy != SSTRING)
- return SynError(it8, "Invalid value '%s' for property '%s'.", Buffer, VarName);
-
- // chop the string as a list of "subkey, value" pairs, using ';' as a separator
- for (Subkey = Buffer; Subkey != NULL; Subkey = Nextkey)
- {
- char *Value, *temp;
-
- // identify token pair boundary
- Nextkey = (char*) strchr(Subkey, ';');
- if(Nextkey)
- *Nextkey++ = '\0';
-
- // for each pair, split the subkey and the value
- Value = (char*) strrchr(Subkey, ',');
- if(Value == NULL)
- return SynError(it8, "Invalid value for property '%s'.", VarName);
-
- // gobble the spaces before the coma, and the coma itself
- temp = Value++;
- do *temp-- = '\0'; while(temp >= Subkey && *temp == ' ');
-
- // gobble any space at the right
- temp = Value + strlen(Value) - 1;
- while(*temp == ' ') *temp-- = '\0';
-
- // trim the strings from the left
- Subkey += strspn(Subkey, " ");
- Value += strspn(Value, " ");
-
- if(Subkey[0] == 0 || Value[0] == 0)
- return SynError(it8, "Invalid value for property '%s'.", VarName);
- AddToList(it8, &GetTable(it8)->HeaderList, VarName, Subkey, Value, WRITE_PAIR);
- }
+ if (Key->WriteAs != WRITE_PAIR) {
+ AddToList(it8, &GetTable(it8)->HeaderList, VarName, NULL, Buffer,
+ (it8->sy == SSTRING) ? WRITE_STRINGIFY : WRITE_UNCOOKED);
+ }
+ else {
+ const char *Subkey;
+ char *Nextkey;
+ if (it8->sy != SSTRING)
+ return SynError(it8, "Invalid value '%s' for property '%s'.", Buffer, VarName);
+
+ // chop the string as a list of "subkey, value" pairs, using ';' as a separator
+ for (Subkey = Buffer; Subkey != NULL; Subkey = Nextkey)
+ {
+ char *Value, *temp;
+
+ // identify token pair boundary
+ Nextkey = (char*)strchr(Subkey, ';');
+ if (Nextkey)
+ *Nextkey++ = '\0';
+
+ // for each pair, split the subkey and the value
+ Value = (char*)strrchr(Subkey, ',');
+ if (Value == NULL)
+ return SynError(it8, "Invalid value for property '%s'.", VarName);
+
+ // gobble the spaces before the coma, and the coma itself
+ temp = Value++;
+ do *temp-- = '\0'; while (temp >= Subkey && *temp == ' ');
+
+ // gobble any space at the right
+ temp = Value + strlen(Value) - 1;
+ while (*temp == ' ') *temp-- = '\0';
+
+ // trim the strings from the left
+ Subkey += strspn(Subkey, " ");
+ Value += strspn(Value, " ");
+
+ if (Subkey[0] == 0 || Value[0] == 0)
+ return SynError(it8, "Invalid value for property '%s'.", VarName);
+ AddToList(it8, &GetTable(it8)->HeaderList, VarName, Subkey, Value, WRITE_PAIR);
}
+ }
- InSymbol(it8);
- break;
+ InSymbol(it8);
+ break;
case SEOLN: break;
diff --git a/src/cmsnamed.c b/src/cmsnamed.c
index 9b27ca0..a8ed7ff 100644
--- a/src/cmsnamed.c
+++ b/src/cmsnamed.c
@@ -517,7 +517,11 @@ cmsBool GrowNamedColorList(cmsNAMEDCOLORLIST* v)
size = v ->Allocated * 2;
// Keep a maximum color lists can grow, 100K entries seems reasonable
- if (size > 1024*100) return FALSE;
+ if (size > 1024 * 100) {
+ _cmsFree(v->ContextID, (void*) v->List);
+ v->List = NULL;
+ return FALSE;
+ }
NewPtr = (_cmsNAMEDCOLOR*) _cmsRealloc(v ->ContextID, v ->List, size * sizeof(_cmsNAMEDCOLOR));
if (NewPtr == NULL)
@@ -539,8 +543,11 @@ cmsNAMEDCOLORLIST* CMSEXPORT cmsAllocNamedColorList(cmsContext ContextID, cmsUIn
v ->nColors = 0;
v ->ContextID = ContextID;
- while (v -> Allocated < n){
- if (!GrowNamedColorList(v)) return NULL;
+ while (v -> Allocated < n) {
+ if (!GrowNamedColorList(v)) {
+ _cmsFree(ContextID, (void*) v);
+ return NULL;
+ }
}
strncpy(v ->Prefix, Prefix, sizeof(v ->Prefix)-1);