Skip to content

Commit ac2e670

Browse files
authored
Merge pull request #171 from scitokens/copilot/fix-07c9230f-8c76-419b-8142-c13e76deeec2
Fix float time claims handling and improve error messages in scitoken_get_expiration
2 parents 8956cca + 215b8ca commit ac2e670

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

src/scitokens.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,18 @@ void scitoken_free_string_list(char **value) {
217217

218218
int scitoken_get_expiration(const SciToken token, long long *expiry,
219219
char **err_msg) {
220+
if (!token) {
221+
if (err_msg) {
222+
*err_msg = strdup("Token cannot be NULL");
223+
}
224+
return -1;
225+
}
226+
if (!expiry) {
227+
if (err_msg) {
228+
*err_msg = strdup("Expiry output parameter cannot be NULL");
229+
}
230+
return -1;
231+
}
220232
scitokens::SciToken *real_token =
221233
reinterpret_cast<scitokens::SciToken *>(token);
222234
if (!real_token->has_claim("exp")) {
@@ -226,7 +238,21 @@ int scitoken_get_expiration(const SciToken token, long long *expiry,
226238

227239
long long result;
228240
try {
229-
result = real_token->get_claim("exp").to_json().get<int64_t>();
241+
auto claim_value = real_token->get_claim("exp").to_json();
242+
if (claim_value.is<int64_t>()) {
243+
// Integer value
244+
result = claim_value.get<int64_t>();
245+
} else if (claim_value.is<double>()) {
246+
// Float value - convert to integer (truncate)
247+
// Float value - convert to integer using std::floor().
248+
// This ensures expiration is not extended by fractional seconds.
249+
result = static_cast<long long>(std::floor(claim_value.get<double>()));
250+
} else {
251+
if (err_msg) {
252+
*err_msg = strdup("'exp' claim must be a number (integer or float)");
253+
}
254+
return -1;
255+
}
230256
} catch (std::exception &exc) {
231257
if (err_msg) {
232258
*err_msg = strdup(exc.what());

test/main.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,41 @@ TEST_F(SerializeTest, ExplicitTime) {
502502
enforcer_destroy(enforcer);
503503
}
504504

505+
TEST_F(SerializeTest, GetExpirationErrorHandling) {
506+
char *err_msg = nullptr;
507+
508+
// Test NULL token handling
509+
long long expiry;
510+
auto rv = scitoken_get_expiration(nullptr, &expiry, &err_msg);
511+
ASSERT_FALSE(rv == 0);
512+
ASSERT_TRUE(err_msg != nullptr);
513+
EXPECT_STREQ(err_msg, "Token cannot be NULL");
514+
free(err_msg);
515+
err_msg = nullptr;
516+
517+
// Test NULL expiry parameter handling
518+
rv = scitoken_get_expiration(m_token.get(), nullptr, &err_msg);
519+
ASSERT_FALSE(rv == 0);
520+
ASSERT_TRUE(err_msg != nullptr);
521+
EXPECT_STREQ(err_msg, "Expiry output parameter cannot be NULL");
522+
free(err_msg);
523+
err_msg = nullptr;
524+
525+
// Test normal operation works
526+
char *token_value = nullptr;
527+
rv = scitoken_serialize(m_token.get(), &token_value, &err_msg);
528+
ASSERT_TRUE(rv == 0) << err_msg;
529+
530+
rv = scitoken_deserialize_v2(token_value, m_read_token.get(), nullptr, &err_msg);
531+
ASSERT_TRUE(rv == 0) << err_msg;
532+
533+
rv = scitoken_get_expiration(m_read_token.get(), &expiry, &err_msg);
534+
ASSERT_TRUE(rv == 0) << err_msg;
535+
ASSERT_TRUE(expiry > 0);
536+
537+
free(token_value);
538+
}
539+
505540
class SerializeNoKidTest : public ::testing::Test {
506541
protected:
507542
void SetUp() override {

0 commit comments

Comments
 (0)