comparison src/c/urweb.c @ 1728:95d3b4f26f59

Ensure proper ordering of <script> execution, to bring identifiers into scope in time
author Adam Chlipala <adam@chlipala.net>
date Fri, 27 Apr 2012 09:43:09 -0400
parents 4df4521fbd3b
children 6817ddd6cf1f
comparison
equal deleted inserted replaced
1727:318ba997a149 1728:95d3b4f26f59
1308 int len = strlen(s); 1308 int len = strlen(s);
1309 1309
1310 uw_check_script(ctx, len + 1); 1310 uw_check_script(ctx, len + 1);
1311 strcpy(ctx->script.front, s); 1311 strcpy(ctx->script.front, s);
1312 ctx->script.front += len; 1312 ctx->script.front += len;
1313 }
1314
1315 const char *uw_Basis_get_script(uw_context ctx, uw_unit u) {
1316 return "<sc>";
1317 } 1313 }
1318 1314
1319 const char *uw_get_real_script(uw_context ctx) { 1315 const char *uw_get_real_script(uw_context ctx) {
1320 if (strstr(ctx->outHeaders.start, "Set-Cookie: ")) { 1316 if (strstr(ctx->outHeaders.start, "Set-Cookie: ")) {
1321 uw_write_script(ctx, "sig=\""); 1317 uw_write_script(ctx, "sig=\"");
3155 ctx->transactionals[i].free(ctx->transactionals[i].data, will_retry); 3151 ctx->transactionals[i].free(ctx->transactionals[i].data, will_retry);
3156 3152
3157 return ctx->app ? ctx->app->db_rollback(ctx) : 0; 3153 return ctx->app ? ctx->app->db_rollback(ctx) : 0;
3158 } 3154 }
3159 3155
3156 static const char begin_xhtml[] = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">";
3157
3160 void uw_commit(uw_context ctx) { 3158 void uw_commit(uw_context ctx) {
3161 int i; 3159 int i;
3162 3160
3163 if (uw_has_error(ctx)) { 3161 if (uw_has_error(ctx)) {
3164 uw_rollback(ctx, 0); 3162 uw_rollback(ctx, 0);
3208 ctx->transactionals[i].free(ctx->transactionals[i].data, 0); 3206 ctx->transactionals[i].free(ctx->transactionals[i].data, 0);
3209 3207
3210 uw_check(ctx, 1); 3208 uw_check(ctx, 1);
3211 *ctx->page.front = 0; 3209 *ctx->page.front = 0;
3212 3210
3213 // Splice script data into appropriate part of page 3211 if (!ctx->returning_indirectly && !strncmp(ctx->page.start, begin_xhtml, sizeof begin_xhtml - 1)) {
3214 if (ctx->returning_indirectly || ctx->script_header[0] == 0) { 3212 char *s;
3215 char *start = strstr(ctx->page.start, "<sc>"); 3213
3216 if (start) { 3214 // Splice script data into appropriate part of page, also adding <head> if needed.
3217 memmove(start, start + 4, uw_buffer_used(&ctx->page) - (start - ctx->page.start) - 4); 3215 s = ctx->page.start + sizeof begin_xhtml - 1;
3218 ctx->page.front -= 4; 3216 s = strchr(s, '<');
3219 } 3217 if (s == NULL) {
3220 } else if (uw_buffer_used(&ctx->script) == 0) { 3218 // Weird. Document has no tags!
3221 size_t len = strlen(ctx->script_header); 3219
3222 char *start = strstr(ctx->page.start, "<sc>"); 3220 uw_write(ctx, "<head></head><body></body>");
3223 if (start) { 3221 uw_check(ctx, 1);
3224 ctx_uw_buffer_check(ctx, "page", &ctx->page, uw_buffer_used(&ctx->page) - 4 + len); 3222 *ctx->page.front = 0;
3225 start = strstr(ctx->page.start, "<sc>"); 3223 } else if (!strncmp(s, "<head>", 6)) {
3226 memmove(start + len, start + 4, uw_buffer_used(&ctx->page) - (start - ctx->page.start) - 3); 3224 // <head> is present. Let's add the <script> tags immediately after it.
3227 ctx->page.front += len - 4; 3225
3228 memcpy(start, ctx->script_header, len); 3226 size_t lenH = strlen(ctx->script_header), len = uw_buffer_used(&ctx->script);
3229 } 3227 size_t lenP = lenH + 40 + len;
3230 } else { 3228 char *start = s + 6, *oldPage = ctx->page.start;
3231 size_t lenH = strlen(ctx->script_header), len = uw_buffer_used(&ctx->script); 3229
3232 size_t lenP = lenH + 40 + len; 3230 ctx_uw_buffer_check(ctx, "page", &ctx->page, uw_buffer_used(&ctx->page) + lenP);
3233 char *start = strstr(ctx->page.start, "<sc>"); 3231 start += ctx->page.start - oldPage;
3234 if (start) { 3232 memmove(start + lenP, start, uw_buffer_used(&ctx->page) - (start - ctx->page.start) + 1);
3235 ctx_uw_buffer_check(ctx, "page", &ctx->page, uw_buffer_used(&ctx->page) - 4 + lenP); 3233 ctx->page.front += lenP;
3236 start = strstr(ctx->page.start, "<sc>");
3237 memmove(start + lenP, start + 4, uw_buffer_used(&ctx->page) - (start - ctx->page.start) - 3);
3238 ctx->page.front += lenP - 4;
3239 memcpy(start, ctx->script_header, lenH); 3234 memcpy(start, ctx->script_header, lenH);
3240 memcpy(start + lenH, "<script type=\"text/javascript\">", 31); 3235 memcpy(start + lenH, "<script type=\"text/javascript\">", 31);
3241 memcpy(start + lenH + 31, ctx->script.start, len); 3236 memcpy(start + lenH + 31, ctx->script.start, len);
3242 memcpy(start + lenH + 31 + len, "</script>", 9); 3237 memcpy(start + lenH + 31 + len, "</script>", 9);
3238 } else {
3239 // No <head>. At this point, add it, with <script> tags inside.
3240
3241 size_t lenH = strlen(ctx->script_header), len = uw_buffer_used(&ctx->script);
3242 size_t lenP = lenH + 53 + len;
3243 char *start = s, *oldPage = ctx->page.start;
3244
3245 printf("start = %ld\n", start - ctx->page.start);
3246
3247 ctx_uw_buffer_check(ctx, "page", &ctx->page, uw_buffer_used(&ctx->page) + lenP);
3248 start += ctx->page.start - oldPage;
3249 printf("page1 = %s\n", ctx->page.start);
3250 memmove(start + lenP, start, uw_buffer_used(&ctx->page) - (start - ctx->page.start) + 1);
3251 printf("page2 = %s\n", ctx->page.start);
3252 ctx->page.front += lenP;
3253 memcpy(start, "<head>", 6);
3254 memcpy(start + 6, ctx->script_header, lenH);
3255 memcpy(start + 6 + lenH, "<script type=\"text/javascript\">", 31);
3256 memcpy(start + 6 + lenH + 31, ctx->script.start, len);
3257 memcpy(start + 6 + lenH + 31 + len, "</script></head>", 16);
3243 } 3258 }
3244 } 3259 }
3245 } 3260 }
3246 3261
3247 3262
3917 } 3932 }
3918 else 3933 else
3919 return NULL; 3934 return NULL;
3920 } 3935 }
3921 3936
3922 static const char begin_xhtml[] = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">";
3923
3924 failure_kind uw_begin_onError(uw_context ctx, char *msg) { 3937 failure_kind uw_begin_onError(uw_context ctx, char *msg) {
3925 int r = setjmp(ctx->jmp_buf); 3938 int r = setjmp(ctx->jmp_buf);
3926 3939
3927 if (ctx->app->on_error) { 3940 if (ctx->app->on_error) {
3928 if (r == 0) { 3941 if (r == 0) {