nsresult SVGPointList::SetValueFromString(const nsAString& aValue) { // The spec says that the list is parsed and accepted up to the first error // encountered, so we must call CopyFrom even if an error occurs. We still // want to throw any error code from setAttribute if there's a problem // though, so we must take care to return any error code. nsresult rv = NS_OK; SVGPointList temp; nsCharSeparatedTokenizerTemplate<IsSVGWhitespace> tokenizer(aValue, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL); while (tokenizer.hasMoreTokens()) { const nsAString& token = tokenizer.nextToken(); RangedPtr<const PRUnichar> iter = SVGContentUtils::GetStartRangedPtr(token); const RangedPtr<const PRUnichar> end = SVGContentUtils::GetEndRangedPtr(token); float x; if (!SVGContentUtils::ParseNumber(iter, end, x)) { rv = NS_ERROR_DOM_SYNTAX_ERR; break; } float y; if (iter == end) { if (!tokenizer.hasMoreTokens() || !SVGContentUtils::ParseNumber(tokenizer.nextToken(), y)) { rv = NS_ERROR_DOM_SYNTAX_ERR; break; } } else { // It's possible for the token to be 10-30 which has // no separator but needs to be parsed as 10, -30 const nsAString& leftOver = Substring(iter.get(), end.get()); if (leftOver[0] != '-' || !SVGContentUtils::ParseNumber(leftOver, y)) { rv = NS_ERROR_DOM_SYNTAX_ERR; break; } } temp.AppendItem(SVGPoint(x, y)); } if (tokenizer.separatorAfterCurrentToken()) { rv = NS_ERROR_DOM_SYNTAX_ERR; // trailing comma } nsresult rv2 = CopyFrom(temp); if (NS_FAILED(rv2)) { return rv2; // prioritize OOM error code over syntax errors } return rv; }
nsresult SVGPointList::SetValueFromString(const nsAString& aValue) { // The spec says that the list is parsed and accepted up to the first error // encountered, so we must call CopyFrom even if an error occurs. We still // want to throw any error code from setAttribute if there's a problem // though, so we must take care to return any error code. nsresult rv = NS_OK; SVGPointList temp; nsCharSeparatedTokenizerTemplate<IsSVGWhitespace> tokenizer(aValue, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL); nsAutoCString str1, str2; // outside loop to minimize memory churn while (tokenizer.hasMoreTokens()) { CopyUTF16toUTF8(tokenizer.nextToken(), str1); const char *token1 = str1.get(); if (*token1 == '\0') { rv = NS_ERROR_DOM_SYNTAX_ERR; break; } char *end; float x = float(PR_strtod(token1, &end)); if (end == token1 || !NS_finite(x)) { rv = NS_ERROR_DOM_SYNTAX_ERR; break; } const char *token2; if (*end == '-') { // It's possible for the token to be 10-30 which has // no separator but needs to be parsed as 10, -30 token2 = end; } else { if (!tokenizer.hasMoreTokens()) { rv = NS_ERROR_DOM_SYNTAX_ERR; break; } CopyUTF16toUTF8(tokenizer.nextToken(), str2); token2 = str2.get(); if (*token2 == '\0') { rv = NS_ERROR_DOM_SYNTAX_ERR; break; } } float y = float(PR_strtod(token2, &end)); if (*end != '\0' || !NS_finite(y)) { rv = NS_ERROR_DOM_SYNTAX_ERR; break; } temp.AppendItem(SVGPoint(x, y)); } if (tokenizer.lastTokenEndedWithSeparator()) { rv = NS_ERROR_DOM_SYNTAX_ERR; // trailing comma } nsresult rv2 = CopyFrom(temp); if (NS_FAILED(rv2)) { return rv2; // prioritize OOM error code over syntax errors } return rv; }